UNPKG

8.55 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 { useFormControl } from "../FormControl/index.js";
9import { styled } from "../zero-styled/index.js";
10import memoTheme from "../utils/memoTheme.js";
11import { useDefaultProps } from "../DefaultPropsProvider/index.js";
12import Typography from "../Typography/index.js";
13import capitalize from "../utils/capitalize.js";
14import formControlLabelClasses, { getFormControlLabelUtilityClasses } from "./formControlLabelClasses.js";
15import formControlState from "../FormControl/formControlState.js";
16import useSlot from "../utils/useSlot.js";
17import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18const useUtilityClasses = ownerState => {
19 const {
20 classes,
21 disabled,
22 labelPlacement,
23 error,
24 required
25 } = ownerState;
26 const slots = {
27 root: ['root', disabled && 'disabled', `labelPlacement${capitalize(labelPlacement)}`, error && 'error', required && 'required'],
28 label: ['label', disabled && 'disabled'],
29 asterisk: ['asterisk', error && 'error']
30 };
31 return composeClasses(slots, getFormControlLabelUtilityClasses, classes);
32};
33export const FormControlLabelRoot = styled('label', {
34 name: 'MuiFormControlLabel',
35 slot: 'Root',
36 overridesResolver: (props, styles) => {
37 const {
38 ownerState
39 } = props;
40 return [{
41 [`& .${formControlLabelClasses.label}`]: styles.label
42 }, styles.root, styles[`labelPlacement${capitalize(ownerState.labelPlacement)}`]];
43 }
44})(memoTheme(({
45 theme
46}) => ({
47 display: 'inline-flex',
48 alignItems: 'center',
49 cursor: 'pointer',
50 // For correct alignment with the text.
51 verticalAlign: 'middle',
52 WebkitTapHighlightColor: 'transparent',
53 marginLeft: -11,
54 marginRight: 16,
55 // used for row presentation of radio/checkbox
56 [`&.${formControlLabelClasses.disabled}`]: {
57 cursor: 'default'
58 },
59 [`& .${formControlLabelClasses.label}`]: {
60 [`&.${formControlLabelClasses.disabled}`]: {
61 color: (theme.vars || theme).palette.text.disabled
62 }
63 },
64 variants: [{
65 props: {
66 labelPlacement: 'start'
67 },
68 style: {
69 flexDirection: 'row-reverse',
70 marginRight: -11
71 }
72 }, {
73 props: {
74 labelPlacement: 'top'
75 },
76 style: {
77 flexDirection: 'column-reverse'
78 }
79 }, {
80 props: {
81 labelPlacement: 'bottom'
82 },
83 style: {
84 flexDirection: 'column'
85 }
86 }, {
87 props: ({
88 labelPlacement
89 }) => labelPlacement === 'start' || labelPlacement === 'top' || labelPlacement === 'bottom',
90 style: {
91 marginLeft: 16 // used for row presentation of radio/checkbox
92 }
93 }]
94})));
95const AsteriskComponent = styled('span', {
96 name: 'MuiFormControlLabel',
97 slot: 'Asterisk',
98 overridesResolver: (props, styles) => styles.asterisk
99})(memoTheme(({
100 theme
101}) => ({
102 [`&.${formControlLabelClasses.error}`]: {
103 color: (theme.vars || theme).palette.error.main
104 }
105})));
106
107/**
108 * Drop-in replacement of the `Radio`, `Switch` and `Checkbox` component.
109 * Use this component if you want to display an extra label.
110 */
111const FormControlLabel = /*#__PURE__*/React.forwardRef(function FormControlLabel(inProps, ref) {
112 const props = useDefaultProps({
113 props: inProps,
114 name: 'MuiFormControlLabel'
115 });
116 const {
117 checked,
118 className,
119 componentsProps = {},
120 control,
121 disabled: disabledProp,
122 disableTypography,
123 inputRef,
124 label: labelProp,
125 labelPlacement = 'end',
126 name,
127 onChange,
128 required: requiredProp,
129 slots = {},
130 slotProps = {},
131 value,
132 ...other
133 } = props;
134 const muiFormControl = useFormControl();
135 const disabled = disabledProp ?? control.props.disabled ?? muiFormControl?.disabled;
136 const required = requiredProp ?? control.props.required;
137 const controlProps = {
138 disabled,
139 required
140 };
141 ['checked', 'name', 'onChange', 'value', 'inputRef'].forEach(key => {
142 if (typeof control.props[key] === 'undefined' && typeof props[key] !== 'undefined') {
143 controlProps[key] = props[key];
144 }
145 });
146 const fcs = formControlState({
147 props,
148 muiFormControl,
149 states: ['error']
150 });
151 const ownerState = {
152 ...props,
153 disabled,
154 labelPlacement,
155 required,
156 error: fcs.error
157 };
158 const classes = useUtilityClasses(ownerState);
159 const externalForwardedProps = {
160 slots,
161 slotProps: {
162 ...componentsProps,
163 ...slotProps
164 }
165 };
166 const [TypographySlot, typographySlotProps] = useSlot('typography', {
167 elementType: Typography,
168 externalForwardedProps,
169 ownerState
170 });
171 let label = labelProp;
172 if (label != null && label.type !== Typography && !disableTypography) {
173 label = /*#__PURE__*/_jsx(TypographySlot, {
174 component: "span",
175 ...typographySlotProps,
176 className: clsx(classes.label, typographySlotProps?.className),
177 children: label
178 });
179 }
180 return /*#__PURE__*/_jsxs(FormControlLabelRoot, {
181 className: clsx(classes.root, className),
182 ownerState: ownerState,
183 ref: ref,
184 ...other,
185 children: [/*#__PURE__*/React.cloneElement(control, controlProps), required ? /*#__PURE__*/_jsxs("div", {
186 children: [label, /*#__PURE__*/_jsxs(AsteriskComponent, {
187 ownerState: ownerState,
188 "aria-hidden": true,
189 className: classes.asterisk,
190 children: ["\u2009", '*']
191 })]
192 }) : label]
193 });
194});
195process.env.NODE_ENV !== "production" ? FormControlLabel.propTypes /* remove-proptypes */ = {
196 // ┌────────────────────────────── Warning ──────────────────────────────┐
197 // │ These PropTypes are generated from the TypeScript type definitions. │
198 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
199 // └─────────────────────────────────────────────────────────────────────┘
200 /**
201 * If `true`, the component appears selected.
202 */
203 checked: PropTypes.bool,
204 /**
205 * Override or extend the styles applied to the component.
206 */
207 classes: PropTypes.object,
208 /**
209 * @ignore
210 */
211 className: PropTypes.string,
212 /**
213 * The props used for each slot inside.
214 * @default {}
215 * @deprecated use the `slotProps` 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.
216 */
217 componentsProps: PropTypes.shape({
218 typography: PropTypes.object
219 }),
220 /**
221 * A control element. For instance, it can be a `Radio`, a `Switch` or a `Checkbox`.
222 */
223 control: PropTypes.element.isRequired,
224 /**
225 * If `true`, the control is disabled.
226 */
227 disabled: PropTypes.bool,
228 /**
229 * If `true`, the label is rendered as it is passed without an additional typography node.
230 */
231 disableTypography: PropTypes.bool,
232 /**
233 * Pass a ref to the `input` element.
234 */
235 inputRef: refType,
236 /**
237 * A text or an element to be used in an enclosing label element.
238 */
239 label: PropTypes.node,
240 /**
241 * The position of the label.
242 * @default 'end'
243 */
244 labelPlacement: PropTypes.oneOf(['bottom', 'end', 'start', 'top']),
245 /**
246 * @ignore
247 */
248 name: PropTypes.string,
249 /**
250 * Callback fired when the state is changed.
251 *
252 * @param {React.SyntheticEvent} event The event source of the callback.
253 * You can pull out the new checked state by accessing `event.target.checked` (boolean).
254 */
255 onChange: PropTypes.func,
256 /**
257 * If `true`, the label will indicate that the `input` is required.
258 */
259 required: PropTypes.bool,
260 /**
261 * The props used for each slot inside.
262 * @default {}
263 */
264 slotProps: PropTypes.shape({
265 typography: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
266 }),
267 /**
268 * The components used for each slot inside.
269 * @default {}
270 */
271 slots: PropTypes.shape({
272 typography: PropTypes.elementType
273 }),
274 /**
275 * The system prop that allows defining system overrides as well as additional CSS styles.
276 */
277 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
278 /**
279 * The value of the component.
280 */
281 value: PropTypes.any
282} : void 0;
283export default FormControlLabel;
\No newline at end of file