UNPKG

10.3 kBJavaScriptView Raw
1"use strict";
2'use client';
3
4var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
6Object.defineProperty(exports, "__esModule", {
7 value: true
8});
9exports.default = void 0;
10var React = _interopRequireWildcard(require("react"));
11var _propTypes = _interopRequireDefault(require("prop-types"));
12var _clsx = _interopRequireDefault(require("clsx"));
13var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
14var _zeroStyled = require("../zero-styled");
15var _DefaultPropsProvider = require("../DefaultPropsProvider");
16var _utils = require("../InputBase/utils");
17var _capitalize = _interopRequireDefault(require("../utils/capitalize"));
18var _isMuiElement = _interopRequireDefault(require("../utils/isMuiElement"));
19var _FormControlContext = _interopRequireDefault(require("./FormControlContext"));
20var _formControlClasses = require("./formControlClasses");
21var _jsxRuntime = require("react/jsx-runtime");
22const useUtilityClasses = ownerState => {
23 const {
24 classes,
25 margin,
26 fullWidth
27 } = ownerState;
28 const slots = {
29 root: ['root', margin !== 'none' && `margin${(0, _capitalize.default)(margin)}`, fullWidth && 'fullWidth']
30 };
31 return (0, _composeClasses.default)(slots, _formControlClasses.getFormControlUtilityClasses, classes);
32};
33const FormControlRoot = (0, _zeroStyled.styled)('div', {
34 name: 'MuiFormControl',
35 slot: 'Root',
36 overridesResolver: ({
37 ownerState
38 }, styles) => {
39 return {
40 ...styles.root,
41 ...styles[`margin${(0, _capitalize.default)(ownerState.margin)}`],
42 ...(ownerState.fullWidth && styles.fullWidth)
43 };
44 }
45})({
46 display: 'inline-flex',
47 flexDirection: 'column',
48 position: 'relative',
49 // Reset fieldset default style.
50 minWidth: 0,
51 padding: 0,
52 margin: 0,
53 border: 0,
54 verticalAlign: 'top',
55 // Fix alignment issue on Safari.
56 variants: [{
57 props: {
58 margin: 'normal'
59 },
60 style: {
61 marginTop: 16,
62 marginBottom: 8
63 }
64 }, {
65 props: {
66 margin: 'dense'
67 },
68 style: {
69 marginTop: 8,
70 marginBottom: 4
71 }
72 }, {
73 props: {
74 fullWidth: true
75 },
76 style: {
77 width: '100%'
78 }
79 }]
80});
81
82/**
83 * Provides context such as filled/focused/error/required for form inputs.
84 * Relying on the context provides high flexibility and ensures that the state always stays
85 * consistent across the children of the `FormControl`.
86 * This context is used by the following components:
87 *
88 * - FormLabel
89 * - FormHelperText
90 * - Input
91 * - InputLabel
92 *
93 * You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
94 *
95 * ```jsx
96 * <FormControl>
97 * <InputLabel htmlFor="my-input">Email address</InputLabel>
98 * <Input id="my-input" aria-describedby="my-helper-text" />
99 * <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
100 * </FormControl>
101 * ```
102 *
103 * ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
104 * For instance, only one input can be focused at the same time, the state shouldn't be shared.
105 */
106const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
107 const props = (0, _DefaultPropsProvider.useDefaultProps)({
108 props: inProps,
109 name: 'MuiFormControl'
110 });
111 const {
112 children,
113 className,
114 color = 'primary',
115 component = 'div',
116 disabled = false,
117 error = false,
118 focused: visuallyFocused,
119 fullWidth = false,
120 hiddenLabel = false,
121 margin = 'none',
122 required = false,
123 size = 'medium',
124 variant = 'outlined',
125 ...other
126 } = props;
127 const ownerState = {
128 ...props,
129 color,
130 component,
131 disabled,
132 error,
133 fullWidth,
134 hiddenLabel,
135 margin,
136 required,
137 size,
138 variant
139 };
140 const classes = useUtilityClasses(ownerState);
141 const [adornedStart, setAdornedStart] = React.useState(() => {
142 // We need to iterate through the children and find the Input in order
143 // to fully support server-side rendering.
144 let initialAdornedStart = false;
145 if (children) {
146 React.Children.forEach(children, child => {
147 if (!(0, _isMuiElement.default)(child, ['Input', 'Select'])) {
148 return;
149 }
150 const input = (0, _isMuiElement.default)(child, ['Select']) ? child.props.input : child;
151 if (input && (0, _utils.isAdornedStart)(input.props)) {
152 initialAdornedStart = true;
153 }
154 });
155 }
156 return initialAdornedStart;
157 });
158 const [filled, setFilled] = React.useState(() => {
159 // We need to iterate through the children and find the Input in order
160 // to fully support server-side rendering.
161 let initialFilled = false;
162 if (children) {
163 React.Children.forEach(children, child => {
164 if (!(0, _isMuiElement.default)(child, ['Input', 'Select'])) {
165 return;
166 }
167 if ((0, _utils.isFilled)(child.props, true) || (0, _utils.isFilled)(child.props.inputProps, true)) {
168 initialFilled = true;
169 }
170 });
171 }
172 return initialFilled;
173 });
174 const [focusedState, setFocused] = React.useState(false);
175 if (disabled && focusedState) {
176 setFocused(false);
177 }
178 const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
179 let registerEffect;
180 const registeredInput = React.useRef(false);
181 if (process.env.NODE_ENV !== 'production') {
182 registerEffect = () => {
183 if (registeredInput.current) {
184 console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
185 }
186 registeredInput.current = true;
187 return () => {
188 registeredInput.current = false;
189 };
190 };
191 }
192 const childContext = React.useMemo(() => {
193 return {
194 adornedStart,
195 setAdornedStart,
196 color,
197 disabled,
198 error,
199 filled,
200 focused,
201 fullWidth,
202 hiddenLabel,
203 size,
204 onBlur: () => {
205 setFocused(false);
206 },
207 onEmpty: () => {
208 setFilled(false);
209 },
210 onFilled: () => {
211 setFilled(true);
212 },
213 onFocus: () => {
214 setFocused(true);
215 },
216 registerEffect,
217 required,
218 variant
219 };
220 }, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, required, size, variant]);
221 return /*#__PURE__*/(0, _jsxRuntime.jsx)(_FormControlContext.default.Provider, {
222 value: childContext,
223 children: /*#__PURE__*/(0, _jsxRuntime.jsx)(FormControlRoot, {
224 as: component,
225 ownerState: ownerState,
226 className: (0, _clsx.default)(classes.root, className),
227 ref: ref,
228 ...other,
229 children: children
230 })
231 });
232});
233process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
234 // ┌────────────────────────────── Warning ──────────────────────────────┐
235 // │ These PropTypes are generated from the TypeScript type definitions. │
236 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
237 // └─────────────────────────────────────────────────────────────────────┘
238 /**
239 * The content of the component.
240 */
241 children: _propTypes.default.node,
242 /**
243 * Override or extend the styles applied to the component.
244 */
245 classes: _propTypes.default.object,
246 /**
247 * @ignore
248 */
249 className: _propTypes.default.string,
250 /**
251 * The color of the component.
252 * It supports both default and custom theme colors, which can be added as shown in the
253 * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
254 * @default 'primary'
255 */
256 color: _propTypes.default /* @typescript-to-proptypes-ignore */.oneOfType([_propTypes.default.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), _propTypes.default.string]),
257 /**
258 * The component used for the root node.
259 * Either a string to use a HTML element or a component.
260 */
261 component: _propTypes.default.elementType,
262 /**
263 * If `true`, the label, input and helper text should be displayed in a disabled state.
264 * @default false
265 */
266 disabled: _propTypes.default.bool,
267 /**
268 * If `true`, the label is displayed in an error state.
269 * @default false
270 */
271 error: _propTypes.default.bool,
272 /**
273 * If `true`, the component is displayed in focused state.
274 */
275 focused: _propTypes.default.bool,
276 /**
277 * If `true`, the component will take up the full width of its container.
278 * @default false
279 */
280 fullWidth: _propTypes.default.bool,
281 /**
282 * If `true`, the label is hidden.
283 * This is used to increase density for a `FilledInput`.
284 * Be sure to add `aria-label` to the `input` element.
285 * @default false
286 */
287 hiddenLabel: _propTypes.default.bool,
288 /**
289 * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
290 * @default 'none'
291 */
292 margin: _propTypes.default.oneOf(['dense', 'none', 'normal']),
293 /**
294 * If `true`, the label will indicate that the `input` is required.
295 * @default false
296 */
297 required: _propTypes.default.bool,
298 /**
299 * The size of the component.
300 * @default 'medium'
301 */
302 size: _propTypes.default /* @typescript-to-proptypes-ignore */.oneOfType([_propTypes.default.oneOf(['medium', 'small']), _propTypes.default.string]),
303 /**
304 * The system prop that allows defining system overrides as well as additional CSS styles.
305 */
306 sx: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object, _propTypes.default.bool])), _propTypes.default.func, _propTypes.default.object]),
307 /**
308 * The variant to use.
309 * @default 'outlined'
310 */
311 variant: _propTypes.default.oneOf(['filled', 'outlined', 'standard'])
312} : void 0;
313var _default = exports.default = FormControl;
\No newline at end of file