UNPKG

8.7 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import refType from '@mui/utils/refType';
7import composeClasses from '@mui/utils/composeClasses';
8import { alpha } from '@mui/system/colorManipulator';
9import SwitchBase from "../internal/SwitchBase.js";
10import RadioButtonIcon from "./RadioButtonIcon.js";
11import capitalize from "../utils/capitalize.js";
12import createChainedFunction from "../utils/createChainedFunction.js";
13import useFormControl from "../FormControl/useFormControl.js";
14import useRadioGroup from "../RadioGroup/useRadioGroup.js";
15import radioClasses, { getRadioUtilityClass } from "./radioClasses.js";
16import rootShouldForwardProp from "../styles/rootShouldForwardProp.js";
17import { styled } from "../zero-styled/index.js";
18import memoTheme from "../utils/memoTheme.js";
19import createSimplePaletteValueFilter from "../utils/createSimplePaletteValueFilter.js";
20import { useDefaultProps } from "../DefaultPropsProvider/index.js";
21import { jsx as _jsx } from "react/jsx-runtime";
22const useUtilityClasses = ownerState => {
23 const {
24 classes,
25 color,
26 size
27 } = ownerState;
28 const slots = {
29 root: ['root', `color${capitalize(color)}`, size !== 'medium' && `size${capitalize(size)}`]
30 };
31 return {
32 ...classes,
33 ...composeClasses(slots, getRadioUtilityClass, classes)
34 };
35};
36const RadioRoot = styled(SwitchBase, {
37 shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
38 name: 'MuiRadio',
39 slot: 'Root',
40 overridesResolver: (props, styles) => {
41 const {
42 ownerState
43 } = props;
44 return [styles.root, ownerState.size !== 'medium' && styles[`size${capitalize(ownerState.size)}`], styles[`color${capitalize(ownerState.color)}`]];
45 }
46})(memoTheme(({
47 theme
48}) => ({
49 color: (theme.vars || theme).palette.text.secondary,
50 [`&.${radioClasses.disabled}`]: {
51 color: (theme.vars || theme).palette.action.disabled
52 },
53 variants: [{
54 props: {
55 color: 'default',
56 disabled: false,
57 disableRipple: false
58 },
59 style: {
60 '&:hover': {
61 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity)
62 }
63 }
64 }, ...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
65 props: {
66 color,
67 disabled: false,
68 disableRipple: false
69 },
70 style: {
71 '&:hover': {
72 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity)
73 }
74 }
75 })), ...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
76 props: {
77 color,
78 disabled: false
79 },
80 style: {
81 [`&.${radioClasses.checked}`]: {
82 color: (theme.vars || theme).palette[color].main
83 }
84 }
85 })), {
86 // Should be last to override other colors
87 props: {
88 disableRipple: false
89 },
90 style: {
91 // Reset on touch devices, it doesn't add specificity
92 '&:hover': {
93 '@media (hover: none)': {
94 backgroundColor: 'transparent'
95 }
96 }
97 }
98 }]
99})));
100function areEqualValues(a, b) {
101 if (typeof b === 'object' && b !== null) {
102 return a === b;
103 }
104
105 // The value could be a number, the DOM will stringify it anyway.
106 return String(a) === String(b);
107}
108const defaultCheckedIcon = /*#__PURE__*/_jsx(RadioButtonIcon, {
109 checked: true
110});
111const defaultIcon = /*#__PURE__*/_jsx(RadioButtonIcon, {});
112const Radio = /*#__PURE__*/React.forwardRef(function Radio(inProps, ref) {
113 const props = useDefaultProps({
114 props: inProps,
115 name: 'MuiRadio'
116 });
117 const {
118 checked: checkedProp,
119 checkedIcon = defaultCheckedIcon,
120 color = 'primary',
121 icon = defaultIcon,
122 name: nameProp,
123 onChange: onChangeProp,
124 size = 'medium',
125 className,
126 disabled: disabledProp,
127 disableRipple = false,
128 ...other
129 } = props;
130 const muiFormControl = useFormControl();
131 let disabled = disabledProp;
132 if (muiFormControl) {
133 if (typeof disabled === 'undefined') {
134 disabled = muiFormControl.disabled;
135 }
136 }
137 disabled ??= false;
138 const ownerState = {
139 ...props,
140 disabled,
141 disableRipple,
142 color,
143 size
144 };
145 const classes = useUtilityClasses(ownerState);
146 const radioGroup = useRadioGroup();
147 let checked = checkedProp;
148 const onChange = createChainedFunction(onChangeProp, radioGroup && radioGroup.onChange);
149 let name = nameProp;
150 if (radioGroup) {
151 if (typeof checked === 'undefined') {
152 checked = areEqualValues(radioGroup.value, props.value);
153 }
154 if (typeof name === 'undefined') {
155 name = radioGroup.name;
156 }
157 }
158 return /*#__PURE__*/_jsx(RadioRoot, {
159 type: "radio",
160 icon: /*#__PURE__*/React.cloneElement(icon, {
161 fontSize: defaultIcon.props.fontSize ?? size
162 }),
163 checkedIcon: /*#__PURE__*/React.cloneElement(checkedIcon, {
164 fontSize: defaultCheckedIcon.props.fontSize ?? size
165 }),
166 disabled: disabled,
167 ownerState: ownerState,
168 classes: classes,
169 name: name,
170 checked: checked,
171 onChange: onChange,
172 ref: ref,
173 className: clsx(classes.root, className),
174 ...other
175 });
176});
177process.env.NODE_ENV !== "production" ? Radio.propTypes /* remove-proptypes */ = {
178 // ┌────────────────────────────── Warning ──────────────────────────────┐
179 // │ These PropTypes are generated from the TypeScript type definitions. │
180 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
181 // └─────────────────────────────────────────────────────────────────────┘
182 /**
183 * If `true`, the component is checked.
184 */
185 checked: PropTypes.bool,
186 /**
187 * The icon to display when the component is checked.
188 * @default <RadioButtonIcon checked />
189 */
190 checkedIcon: PropTypes.node,
191 /**
192 * Override or extend the styles applied to the component.
193 */
194 classes: PropTypes.object,
195 /**
196 * @ignore
197 */
198 className: PropTypes.string,
199 /**
200 * The color of the component.
201 * It supports both default and custom theme colors, which can be added as shown in the
202 * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
203 * @default 'primary'
204 */
205 color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['default', 'primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
206 /**
207 * If `true`, the component is disabled.
208 */
209 disabled: PropTypes.bool,
210 /**
211 * If `true`, the ripple effect is disabled.
212 * @default false
213 */
214 disableRipple: PropTypes.bool,
215 /**
216 * The icon to display when the component is unchecked.
217 * @default <RadioButtonIcon />
218 */
219 icon: PropTypes.node,
220 /**
221 * The id of the `input` element.
222 */
223 id: PropTypes.string,
224 /**
225 * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
226 */
227 inputProps: PropTypes.object,
228 /**
229 * Pass a ref to the `input` element.
230 */
231 inputRef: refType,
232 /**
233 * Name attribute of the `input` element.
234 */
235 name: PropTypes.string,
236 /**
237 * Callback fired when the state is changed.
238 *
239 * @param {React.ChangeEvent<HTMLInputElement>} event The event source of the callback.
240 * You can pull out the new value by accessing `event.target.value` (string).
241 * You can pull out the new checked state by accessing `event.target.checked` (boolean).
242 */
243 onChange: PropTypes.func,
244 /**
245 * If `true`, the `input` element is required.
246 * @default false
247 */
248 required: PropTypes.bool,
249 /**
250 * The size of the component.
251 * `small` is equivalent to the dense radio styling.
252 * @default 'medium'
253 */
254 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
255 /**
256 * The system prop that allows defining system overrides as well as additional CSS styles.
257 */
258 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
259 /**
260 * The value of the component. The DOM API casts this to a string.
261 */
262 value: PropTypes.any
263} : void 0;
264export default Radio;
\No newline at end of file