UNPKG

10 kBJavaScriptView Raw
1'use client';
2
3// @inheritedComponent ButtonBase
4import * as React from 'react';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import resolveProps from '@mui/utils/resolveProps';
8import composeClasses from '@mui/utils/composeClasses';
9import { alpha } from '@mui/system/colorManipulator';
10import ButtonBase from "../ButtonBase/index.js";
11import capitalize from "../utils/capitalize.js";
12import { styled } from "../zero-styled/index.js";
13import memoTheme from "../utils/memoTheme.js";
14import createSimplePaletteValueFilter from "../utils/createSimplePaletteValueFilter.js";
15import { useDefaultProps } from "../DefaultPropsProvider/index.js";
16import toggleButtonClasses, { getToggleButtonUtilityClass } from "./toggleButtonClasses.js";
17import ToggleButtonGroupContext from "../ToggleButtonGroup/ToggleButtonGroupContext.js";
18import ToggleButtonGroupButtonContext from "../ToggleButtonGroup/ToggleButtonGroupButtonContext.js";
19import isValueSelected from "../ToggleButtonGroup/isValueSelected.js";
20import { jsx as _jsx } from "react/jsx-runtime";
21const useUtilityClasses = ownerState => {
22 const {
23 classes,
24 fullWidth,
25 selected,
26 disabled,
27 size,
28 color
29 } = ownerState;
30 const slots = {
31 root: ['root', selected && 'selected', disabled && 'disabled', fullWidth && 'fullWidth', `size${capitalize(size)}`, color]
32 };
33 return composeClasses(slots, getToggleButtonUtilityClass, classes);
34};
35const ToggleButtonRoot = styled(ButtonBase, {
36 name: 'MuiToggleButton',
37 slot: 'Root',
38 overridesResolver: (props, styles) => {
39 const {
40 ownerState
41 } = props;
42 return [styles.root, styles[`size${capitalize(ownerState.size)}`]];
43 }
44})(memoTheme(({
45 theme
46}) => ({
47 ...theme.typography.button,
48 borderRadius: (theme.vars || theme).shape.borderRadius,
49 padding: 11,
50 border: `1px solid ${(theme.vars || theme).palette.divider}`,
51 color: (theme.vars || theme).palette.action.active,
52 [`&.${toggleButtonClasses.disabled}`]: {
53 color: (theme.vars || theme).palette.action.disabled,
54 border: `1px solid ${(theme.vars || theme).palette.action.disabledBackground}`
55 },
56 '&:hover': {
57 textDecoration: 'none',
58 // Reset on mouse devices
59 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity),
60 '@media (hover: none)': {
61 backgroundColor: 'transparent'
62 }
63 },
64 variants: [{
65 props: {
66 color: 'standard'
67 },
68 style: {
69 [`&.${toggleButtonClasses.selected}`]: {
70 color: (theme.vars || theme).palette.text.primary,
71 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity),
72 '&:hover': {
73 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
74 // Reset on touch devices, it doesn't add specificity
75 '@media (hover: none)': {
76 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity)
77 }
78 }
79 }
80 }
81 }, ...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
82 props: {
83 color
84 },
85 style: {
86 [`&.${toggleButtonClasses.selected}`]: {
87 color: (theme.vars || theme).palette[color].main,
88 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity),
89 '&:hover': {
90 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
91 // Reset on touch devices, it doesn't add specificity
92 '@media (hover: none)': {
93 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity)
94 }
95 }
96 }
97 }
98 })), {
99 props: {
100 fullWidth: true
101 },
102 style: {
103 width: '100%'
104 }
105 }, {
106 props: {
107 size: 'small'
108 },
109 style: {
110 padding: 7,
111 fontSize: theme.typography.pxToRem(13)
112 }
113 }, {
114 props: {
115 size: 'large'
116 },
117 style: {
118 padding: 15,
119 fontSize: theme.typography.pxToRem(15)
120 }
121 }]
122})));
123const ToggleButton = /*#__PURE__*/React.forwardRef(function ToggleButton(inProps, ref) {
124 // props priority: `inProps` > `contextProps` > `themeDefaultProps`
125 const {
126 value: contextValue,
127 ...contextProps
128 } = React.useContext(ToggleButtonGroupContext);
129 const toggleButtonGroupButtonContextPositionClassName = React.useContext(ToggleButtonGroupButtonContext);
130 const resolvedProps = resolveProps({
131 ...contextProps,
132 selected: isValueSelected(inProps.value, contextValue)
133 }, inProps);
134 const props = useDefaultProps({
135 props: resolvedProps,
136 name: 'MuiToggleButton'
137 });
138 const {
139 children,
140 className,
141 color = 'standard',
142 disabled = false,
143 disableFocusRipple = false,
144 fullWidth = false,
145 onChange,
146 onClick,
147 selected,
148 size = 'medium',
149 value,
150 ...other
151 } = props;
152 const ownerState = {
153 ...props,
154 color,
155 disabled,
156 disableFocusRipple,
157 fullWidth,
158 size
159 };
160 const classes = useUtilityClasses(ownerState);
161 const handleChange = event => {
162 if (onClick) {
163 onClick(event, value);
164 if (event.defaultPrevented) {
165 return;
166 }
167 }
168 if (onChange) {
169 onChange(event, value);
170 }
171 };
172 const positionClassName = toggleButtonGroupButtonContextPositionClassName || '';
173 return /*#__PURE__*/_jsx(ToggleButtonRoot, {
174 className: clsx(contextProps.className, classes.root, className, positionClassName),
175 disabled: disabled,
176 focusRipple: !disableFocusRipple,
177 ref: ref,
178 onClick: handleChange,
179 onChange: onChange,
180 value: value,
181 ownerState: ownerState,
182 "aria-pressed": selected,
183 ...other,
184 children: children
185 });
186});
187process.env.NODE_ENV !== "production" ? ToggleButton.propTypes /* remove-proptypes */ = {
188 // ┌────────────────────────────── Warning ──────────────────────────────┐
189 // │ These PropTypes are generated from the TypeScript type definitions. │
190 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
191 // └─────────────────────────────────────────────────────────────────────┘
192 /**
193 * The content of the component.
194 */
195 children: PropTypes.node,
196 /**
197 * Override or extend the styles applied to the component.
198 */
199 classes: PropTypes.object,
200 /**
201 * @ignore
202 */
203 className: PropTypes.string,
204 /**
205 * The color of the button when it is in an active state.
206 * It supports both default and custom theme colors, which can be added as shown in the
207 * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
208 * @default 'standard'
209 */
210 color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['standard', 'primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
211 /**
212 * If `true`, the component is disabled.
213 * @default false
214 */
215 disabled: PropTypes.bool,
216 /**
217 * If `true`, the keyboard focus ripple is disabled.
218 * @default false
219 */
220 disableFocusRipple: PropTypes.bool,
221 /**
222 * If `true`, the ripple effect is disabled.
223 *
224 * ⚠️ Without a ripple there is no styling for :focus-visible by default. Be sure
225 * to highlight the element by applying separate styles with the `.Mui-focusVisible` class.
226 * @default false
227 */
228 disableRipple: PropTypes.bool,
229 /**
230 * If `true`, the button will take up the full width of its container.
231 * @default false
232 */
233 fullWidth: PropTypes.bool,
234 /**
235 * Callback fired when the state changes.
236 *
237 * @param {React.MouseEvent<HTMLElement>} event The event source of the callback.
238 * @param {any} value of the selected button.
239 */
240 onChange: PropTypes.func,
241 /**
242 * Callback fired when the button is clicked.
243 *
244 * @param {React.MouseEvent<HTMLElement>} event The event source of the callback.
245 * @param {any} value of the selected button.
246 */
247 onClick: PropTypes.func,
248 /**
249 * If `true`, the button is rendered in an active state.
250 */
251 selected: PropTypes.bool,
252 /**
253 * The size of the component.
254 * The prop defaults to the value inherited from the parent ToggleButtonGroup component.
255 * @default 'medium'
256 */
257 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['small', 'medium', 'large']), PropTypes.string]),
258 /**
259 * The system prop that allows defining system overrides as well as additional CSS styles.
260 */
261 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
262 /**
263 * The value to associate with the button when selected in a
264 * ToggleButtonGroup.
265 */
266 value: PropTypes /* @typescript-to-proptypes-ignore */.any.isRequired
267} : void 0;
268export default ToggleButton;
\No newline at end of file