From a412eac068a618e0584a9d9fc2fae636eb544fac Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Wed, 28 Dec 2022 10:28:57 -0500 Subject: [PATCH] [Joy][docs] Add documentation for `Input` component (#35482) --- docs/data/joy/components/input/BasicInput.js | 6 + docs/data/joy/components/input/BasicInput.tsx | 6 + .../components/input/BasicInput.tsx.preview | 1 + docs/data/joy/components/input/InputColors.js | 22 +++ .../data/joy/components/input/InputColors.tsx | 22 +++ .../components/input/InputColors.tsx.preview | 4 + .../joy/components/input/InputDecorators.js | 31 ++++ .../joy/components/input/InputDecorators.tsx | 31 ++++ docs/data/joy/components/input/InputField.js | 15 ++ docs/data/joy/components/input/InputField.tsx | 15 ++ .../components/input/InputField.tsx.preview | 5 + .../joy/components/input/InputFormProps.js | 33 ++++ .../joy/components/input/InputFormProps.tsx | 33 ++++ .../input/InputFormProps.tsx.preview | 13 ++ docs/data/joy/components/input/InputSizes.js | 13 ++ docs/data/joy/components/input/InputSizes.tsx | 13 ++ .../components/input/InputSizes.tsx.preview | 3 + .../joy/components/input/InputSlotProps.js | 18 +++ .../joy/components/input/InputSlotProps.tsx | 18 +++ .../input/InputSlotProps.tsx.preview | 11 ++ .../joy/components/input/InputSubscription.js | 77 ++++++++++ .../input/InputSubscription.preview | 8 + .../components/input/InputSubscription.tsx | 79 ++++++++++ docs/data/joy/components/input/InputUsage.js | 41 +++++ .../joy/components/input/InputValidation.js | 11 ++ .../joy/components/input/InputValidation.tsx | 11 ++ .../input/InputValidation.tsx.preview | 1 + .../joy/components/input/InputVariables.js | 69 +++++++++ .../joy/components/input/InputVariants.js | 22 +++ .../joy/components/input/InputVariants.tsx | 22 +++ .../input/InputVariants.tsx.preview | 4 + docs/data/joy/components/input/input.md | 130 ++++++++++++++++ docs/data/joy/pages.ts | 5 +- docs/pages/joy-ui/react-input.js | 7 + docs/public/_redirects | 1 + .../modules/components/JoyVariablesDemo.tsx | 145 ++++++++++-------- 36 files changed, 876 insertions(+), 70 deletions(-) create mode 100644 docs/data/joy/components/input/BasicInput.js create mode 100644 docs/data/joy/components/input/BasicInput.tsx create mode 100644 docs/data/joy/components/input/BasicInput.tsx.preview create mode 100644 docs/data/joy/components/input/InputColors.js create mode 100644 docs/data/joy/components/input/InputColors.tsx create mode 100644 docs/data/joy/components/input/InputColors.tsx.preview create mode 100644 docs/data/joy/components/input/InputDecorators.js create mode 100644 docs/data/joy/components/input/InputDecorators.tsx create mode 100644 docs/data/joy/components/input/InputField.js create mode 100644 docs/data/joy/components/input/InputField.tsx create mode 100644 docs/data/joy/components/input/InputField.tsx.preview create mode 100644 docs/data/joy/components/input/InputFormProps.js create mode 100644 docs/data/joy/components/input/InputFormProps.tsx create mode 100644 docs/data/joy/components/input/InputFormProps.tsx.preview create mode 100644 docs/data/joy/components/input/InputSizes.js create mode 100644 docs/data/joy/components/input/InputSizes.tsx create mode 100644 docs/data/joy/components/input/InputSizes.tsx.preview create mode 100644 docs/data/joy/components/input/InputSlotProps.js create mode 100644 docs/data/joy/components/input/InputSlotProps.tsx create mode 100644 docs/data/joy/components/input/InputSlotProps.tsx.preview create mode 100644 docs/data/joy/components/input/InputSubscription.js create mode 100644 docs/data/joy/components/input/InputSubscription.preview create mode 100644 docs/data/joy/components/input/InputSubscription.tsx create mode 100644 docs/data/joy/components/input/InputUsage.js create mode 100644 docs/data/joy/components/input/InputValidation.js create mode 100644 docs/data/joy/components/input/InputValidation.tsx create mode 100644 docs/data/joy/components/input/InputValidation.tsx.preview create mode 100644 docs/data/joy/components/input/InputVariables.js create mode 100644 docs/data/joy/components/input/InputVariants.js create mode 100644 docs/data/joy/components/input/InputVariants.tsx create mode 100644 docs/data/joy/components/input/InputVariants.tsx.preview create mode 100644 docs/data/joy/components/input/input.md create mode 100644 docs/pages/joy-ui/react-input.js diff --git a/docs/data/joy/components/input/BasicInput.js b/docs/data/joy/components/input/BasicInput.js new file mode 100644 index 00000000000000..7de6710986ced3 --- /dev/null +++ b/docs/data/joy/components/input/BasicInput.js @@ -0,0 +1,6 @@ +import * as React from 'react'; +import Input from '@mui/joy/Input'; + +export default function BasicInput() { + return ; +} diff --git a/docs/data/joy/components/input/BasicInput.tsx b/docs/data/joy/components/input/BasicInput.tsx new file mode 100644 index 00000000000000..7de6710986ced3 --- /dev/null +++ b/docs/data/joy/components/input/BasicInput.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; +import Input from '@mui/joy/Input'; + +export default function BasicInput() { + return ; +} diff --git a/docs/data/joy/components/input/BasicInput.tsx.preview b/docs/data/joy/components/input/BasicInput.tsx.preview new file mode 100644 index 00000000000000..c02c7c3762aebe --- /dev/null +++ b/docs/data/joy/components/input/BasicInput.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/joy/components/input/InputColors.js b/docs/data/joy/components/input/InputColors.js new file mode 100644 index 00000000000000..c13f97c4fa43b2 --- /dev/null +++ b/docs/data/joy/components/input/InputColors.js @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; + +export default function InputColors() { + return ( + + + + + + + ); +} diff --git a/docs/data/joy/components/input/InputColors.tsx b/docs/data/joy/components/input/InputColors.tsx new file mode 100644 index 00000000000000..c13f97c4fa43b2 --- /dev/null +++ b/docs/data/joy/components/input/InputColors.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; + +export default function InputColors() { + return ( + + + + + + + ); +} diff --git a/docs/data/joy/components/input/InputColors.tsx.preview b/docs/data/joy/components/input/InputColors.tsx.preview new file mode 100644 index 00000000000000..4ae6ad599226a9 --- /dev/null +++ b/docs/data/joy/components/input/InputColors.tsx.preview @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/data/joy/components/input/InputDecorators.js b/docs/data/joy/components/input/InputDecorators.js new file mode 100644 index 00000000000000..48c7eb82123de3 --- /dev/null +++ b/docs/data/joy/components/input/InputDecorators.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import Divider from '@mui/joy/Divider'; +import Input from '@mui/joy/Input'; +import Select from '@mui/joy/Select'; +import Option from '@mui/joy/Option'; + +export default function InputDecorators() { + const [currency, setCurrency] = React.useState('dollar'); + return ( + + + + + } + sx={{ width: 300 }} + /> + ); +} diff --git a/docs/data/joy/components/input/InputDecorators.tsx b/docs/data/joy/components/input/InputDecorators.tsx new file mode 100644 index 00000000000000..64f1337e341098 --- /dev/null +++ b/docs/data/joy/components/input/InputDecorators.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import Divider from '@mui/joy/Divider'; +import Input from '@mui/joy/Input'; +import Select from '@mui/joy/Select'; +import Option from '@mui/joy/Option'; + +export default function InputDecorators() { + const [currency, setCurrency] = React.useState('dollar'); + return ( + + + + + } + sx={{ width: 300 }} + /> + ); +} diff --git a/docs/data/joy/components/input/InputField.js b/docs/data/joy/components/input/InputField.js new file mode 100644 index 00000000000000..563cc7b2f3db53 --- /dev/null +++ b/docs/data/joy/components/input/InputField.js @@ -0,0 +1,15 @@ +import * as React from 'react'; +import FormControl from '@mui/joy/FormControl'; +import FormLabel from '@mui/joy/FormLabel'; +import FormHelperText from '@mui/joy/FormHelperText'; +import Input from '@mui/joy/Input'; + +export default function InputField() { + return ( + + Label + + This is a helper text. + + ); +} diff --git a/docs/data/joy/components/input/InputField.tsx b/docs/data/joy/components/input/InputField.tsx new file mode 100644 index 00000000000000..563cc7b2f3db53 --- /dev/null +++ b/docs/data/joy/components/input/InputField.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import FormControl from '@mui/joy/FormControl'; +import FormLabel from '@mui/joy/FormLabel'; +import FormHelperText from '@mui/joy/FormHelperText'; +import Input from '@mui/joy/Input'; + +export default function InputField() { + return ( + + Label + + This is a helper text. + + ); +} diff --git a/docs/data/joy/components/input/InputField.tsx.preview b/docs/data/joy/components/input/InputField.tsx.preview new file mode 100644 index 00000000000000..96205c163b0132 --- /dev/null +++ b/docs/data/joy/components/input/InputField.tsx.preview @@ -0,0 +1,5 @@ + + Label + + This is a helper text. + \ No newline at end of file diff --git a/docs/data/joy/components/input/InputFormProps.js b/docs/data/joy/components/input/InputFormProps.js new file mode 100644 index 00000000000000..a198681d470d5c --- /dev/null +++ b/docs/data/joy/components/input/InputFormProps.js @@ -0,0 +1,33 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Button from '@mui/joy/Button'; +import Input from '@mui/joy/Input'; + +export default function InputFormProps() { + return ( + +
{ + event.preventDefault(); + }} + > + + + +
+
+ ); +} diff --git a/docs/data/joy/components/input/InputFormProps.tsx b/docs/data/joy/components/input/InputFormProps.tsx new file mode 100644 index 00000000000000..a198681d470d5c --- /dev/null +++ b/docs/data/joy/components/input/InputFormProps.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Button from '@mui/joy/Button'; +import Input from '@mui/joy/Input'; + +export default function InputFormProps() { + return ( + +
{ + event.preventDefault(); + }} + > + + + +
+
+ ); +} diff --git a/docs/data/joy/components/input/InputFormProps.tsx.preview b/docs/data/joy/components/input/InputFormProps.tsx.preview new file mode 100644 index 00000000000000..b56827f175d39d --- /dev/null +++ b/docs/data/joy/components/input/InputFormProps.tsx.preview @@ -0,0 +1,13 @@ +
{ + event.preventDefault(); + }} +> + + + +
\ No newline at end of file diff --git a/docs/data/joy/components/input/InputSizes.js b/docs/data/joy/components/input/InputSizes.js new file mode 100644 index 00000000000000..018fa03368ffd7 --- /dev/null +++ b/docs/data/joy/components/input/InputSizes.js @@ -0,0 +1,13 @@ +import * as React from 'react'; +import Input from '@mui/joy/Input'; +import Stack from '@mui/joy/Stack'; + +export default function InputSizes() { + return ( + + + + + + ); +} diff --git a/docs/data/joy/components/input/InputSizes.tsx b/docs/data/joy/components/input/InputSizes.tsx new file mode 100644 index 00000000000000..018fa03368ffd7 --- /dev/null +++ b/docs/data/joy/components/input/InputSizes.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import Input from '@mui/joy/Input'; +import Stack from '@mui/joy/Stack'; + +export default function InputSizes() { + return ( + + + + + + ); +} diff --git a/docs/data/joy/components/input/InputSizes.tsx.preview b/docs/data/joy/components/input/InputSizes.tsx.preview new file mode 100644 index 00000000000000..7dfbc51f0b5cfa --- /dev/null +++ b/docs/data/joy/components/input/InputSizes.tsx.preview @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/docs/data/joy/components/input/InputSlotProps.js b/docs/data/joy/components/input/InputSlotProps.js new file mode 100644 index 00000000000000..afe4da94c17298 --- /dev/null +++ b/docs/data/joy/components/input/InputSlotProps.js @@ -0,0 +1,18 @@ +import * as React from 'react'; +import Input from '@mui/joy/Input'; + +export default function InputSlotProps() { + return ( + + ); +} diff --git a/docs/data/joy/components/input/InputSlotProps.tsx b/docs/data/joy/components/input/InputSlotProps.tsx new file mode 100644 index 00000000000000..afe4da94c17298 --- /dev/null +++ b/docs/data/joy/components/input/InputSlotProps.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import Input from '@mui/joy/Input'; + +export default function InputSlotProps() { + return ( + + ); +} diff --git a/docs/data/joy/components/input/InputSlotProps.tsx.preview b/docs/data/joy/components/input/InputSlotProps.tsx.preview new file mode 100644 index 00000000000000..074cffa80faeb2 --- /dev/null +++ b/docs/data/joy/components/input/InputSlotProps.tsx.preview @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/docs/data/joy/components/input/InputSubscription.js b/docs/data/joy/components/input/InputSubscription.js new file mode 100644 index 00000000000000..5280acf6e6d2c5 --- /dev/null +++ b/docs/data/joy/components/input/InputSubscription.js @@ -0,0 +1,77 @@ +import * as React from 'react'; +import FormControl from '@mui/joy/FormControl'; +import FormLabel from '@mui/joy/FormLabel'; +import FormHelperText from '@mui/joy/FormHelperText'; +import Input from '@mui/joy/Input'; +import Button from '@mui/joy/Button'; + +export default function InputSubscription() { + const [data, setData] = React.useState({ + email: '', + status: 'initial', + }); + + const handleSubmit = (event) => { + event.preventDefault(); + setData((current) => ({ ...current, status: 'loading' })); + try { + // Replace timeout with real backend operation + setTimeout(() => { + setData({ email: '', status: 'sent' }); + }, 1500); + } catch (error) { + setData((current) => ({ ...current, status: 'failure' })); + } + }; + + return ( +
+ + ({ + '--FormLabel-color': theme.vars.palette.primary.plainColor, + })} + > + MUI Newsletter + + + setData({ email: event.target.value, status: 'initial' }) + } + error={data.status === 'failure'} + endDecorator={ + + } + /> + {data.status === 'failure' && ( + ({ color: theme.vars.palette.danger[400] })} + > + Oops! something went wrong, please try again later. + + )} + + {data.status === 'sent' && ( + ({ color: theme.vars.palette.primary[400] })} + > + You are all set! + + )} + +
+ ); +} diff --git a/docs/data/joy/components/input/InputSubscription.preview b/docs/data/joy/components/input/InputSubscription.preview new file mode 100644 index 00000000000000..ac2260335145a2 --- /dev/null +++ b/docs/data/joy/components/input/InputSubscription.preview @@ -0,0 +1,8 @@ + + Subscribe + + } +/> \ No newline at end of file diff --git a/docs/data/joy/components/input/InputSubscription.tsx b/docs/data/joy/components/input/InputSubscription.tsx new file mode 100644 index 00000000000000..f07edccb1a352d --- /dev/null +++ b/docs/data/joy/components/input/InputSubscription.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import FormControl from '@mui/joy/FormControl'; +import FormLabel from '@mui/joy/FormLabel'; +import FormHelperText from '@mui/joy/FormHelperText'; +import Input from '@mui/joy/Input'; +import Button from '@mui/joy/Button'; + +export default function InputSubscription() { + const [data, setData] = React.useState<{ + email: string; + status: 'initial' | 'loading' | 'failure' | 'sent'; + }>({ + email: '', + status: 'initial', + }); + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + setData((current) => ({ ...current, status: 'loading' })); + try { + // Replace timeout with real backend operation + setTimeout(() => { + setData({ email: '', status: 'sent' }); + }, 1500); + } catch (error) { + setData((current) => ({ ...current, status: 'failure' })); + } + }; + + return ( +
+ + ({ + '--FormLabel-color': theme.vars.palette.primary.plainColor, + })} + > + MUI Newsletter + + + setData({ email: event.target.value, status: 'initial' }) + } + error={data.status === 'failure'} + endDecorator={ + + } + /> + {data.status === 'failure' && ( + ({ color: theme.vars.palette.danger[400] })} + > + Oops! something went wrong, please try again later. + + )} + {data.status === 'sent' && ( + ({ color: theme.vars.palette.primary[400] })} + > + You are all set! + + )} + +
+ ); +} diff --git a/docs/data/joy/components/input/InputUsage.js b/docs/data/joy/components/input/InputUsage.js new file mode 100644 index 00000000000000..766d20007f102c --- /dev/null +++ b/docs/data/joy/components/input/InputUsage.js @@ -0,0 +1,41 @@ +import * as React from 'react'; +import JoyUsageDemo from 'docs/src/modules/components/JoyUsageDemo'; +import Input from '@mui/joy/Input'; + +export default function InputUsage() { + return ( + } + /> + ); +} diff --git a/docs/data/joy/components/input/InputValidation.js b/docs/data/joy/components/input/InputValidation.js new file mode 100644 index 00000000000000..daec7adf96e884 --- /dev/null +++ b/docs/data/joy/components/input/InputValidation.js @@ -0,0 +1,11 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; + +export default function InputValidation() { + return ( + + + + ); +} diff --git a/docs/data/joy/components/input/InputValidation.tsx b/docs/data/joy/components/input/InputValidation.tsx new file mode 100644 index 00000000000000..daec7adf96e884 --- /dev/null +++ b/docs/data/joy/components/input/InputValidation.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; + +export default function InputValidation() { + return ( + + + + ); +} diff --git a/docs/data/joy/components/input/InputValidation.tsx.preview b/docs/data/joy/components/input/InputValidation.tsx.preview new file mode 100644 index 00000000000000..8b8c0b28d7458d --- /dev/null +++ b/docs/data/joy/components/input/InputValidation.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/joy/components/input/InputVariables.js b/docs/data/joy/components/input/InputVariables.js new file mode 100644 index 00000000000000..07a23b039ac1c9 --- /dev/null +++ b/docs/data/joy/components/input/InputVariables.js @@ -0,0 +1,69 @@ +import * as React from 'react'; +import JoyVariablesDemo from 'docs/src/modules/components/JoyVariablesDemo'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; +import Button from '@mui/joy/Button'; +import MailIcon from '@mui/icons-material/Mail'; + +export default function InputVariables() { + return ( + `} + endDecorator={}${formattedSx ? `${formattedSx}>` : '\n>'}`} + data={[ + { + var: '--Input-radius', + defaultValue: '8px', + }, + { + var: '--Input-gap', + defaultValue: '8px', + }, + { + var: '--Input-placeholderOpacity', + defaultValue: 0.5, + inputAttributes: { + min: 0.1, + max: 1, + step: 0.1, + }, + }, + { + var: '--Input-focusedThickness', + defaultValue: '2px', + }, + { + var: '--Input-minHeight', + defaultValue: '40px', + }, + { + var: '--Input-paddingInline', + defaultValue: '12px', + }, + { + var: '--Input-decorator-childHeight', + defaultValue: '32px', + }, + ]} + renderDemo={(sx) => ( + + } + endDecorator={} + placeholder="Type in here…" + sx={sx} + /> + + )} + /> + ); +} diff --git a/docs/data/joy/components/input/InputVariants.js b/docs/data/joy/components/input/InputVariants.js new file mode 100644 index 00000000000000..9adc36009ed771 --- /dev/null +++ b/docs/data/joy/components/input/InputVariants.js @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; + +export default function InputVariants() { + return ( + + + + + + + ); +} diff --git a/docs/data/joy/components/input/InputVariants.tsx b/docs/data/joy/components/input/InputVariants.tsx new file mode 100644 index 00000000000000..9adc36009ed771 --- /dev/null +++ b/docs/data/joy/components/input/InputVariants.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Box from '@mui/joy/Box'; +import Input from '@mui/joy/Input'; + +export default function InputVariants() { + return ( + + + + + + + ); +} diff --git a/docs/data/joy/components/input/InputVariants.tsx.preview b/docs/data/joy/components/input/InputVariants.tsx.preview new file mode 100644 index 00000000000000..d4e040e53497f2 --- /dev/null +++ b/docs/data/joy/components/input/InputVariants.tsx.preview @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/data/joy/components/input/input.md b/docs/data/joy/components/input/input.md new file mode 100644 index 00000000000000..88b3133b5a8992 --- /dev/null +++ b/docs/data/joy/components/input/input.md @@ -0,0 +1,130 @@ +--- +product: joy-ui +title: React Input component +unstyled: /base/react-input/ +--- + +# Input + +

An input is a UI element that accepts text data from the user.

+ +## Introduction + +The Input component replaces the native HTML `` tag, and offers expanded customization and accessibility features. + +{{"demo": "InputUsage.js", "hideToolbar": true, "bg": "gradient"}} + +{{"component": "modules/components/ComponentLinkHeader.js", "design": false}} + +## Basics + +```jsx +import Input from '@mui/joy/Input'; +``` + +{{"demo": "BasicInput.js"}} + +## Customization + +### Variants + +The input component supports the four global variants: solid (default), soft, outlined, and plain. + +{{"demo": "InputVariants.js"}} + +:::info +To learn how to add more variants to the component, check out [Themed components—Extend variants](/joy-ui/customization/themed-components/#extend-variants). +::: + +### Sizes + +The input component comes with three sizes out of the box: `sm`, `md` (the default), and `lg`. + +{{"demo": "InputSizes.js"}} + +:::info +To learn how to add more sizes to the component, check out [Themed components—Extend sizes](/joy-ui/customization/themed-components/#extend-sizes). +::: + +### Colors + +Toggle the palette that's being used to color the by text field by using the `color` prop. + +{{"demo": "InputColors.js"}} + +### Form props + +Standard form attributes are supported e.g. `required`, `disabled`, etc. + +{{"demo": "InputFormProps.js"}} + +### Validation + +To toggle the error state, use the `error` prop. + +{{"demo": "InputValidation.js"}} + +Note that using the `color` prop with danger as value gets the same result: + +```js + +``` + +### Decorators + +Use the `startDecorator` and/or `endDecorator` props to add supporting icons or elements to the input. + +It's usually more common to see input components using decorators at the top and bottom. + +{{"demo": "InputDecorators.js"}} + +## Inner HTML input + +To pass any props to the inner HTML ``, use `slotProps={{ input: { ...props } }}`. + +{{"demo": "InputSlotProps.js"}} + +## Common examples + +### Newsletter Subscription + +{{"demo": "InputSubscription.js"}} + +## CSS variables + +Play around with all the CSS variables available in the input component to see how the design changes. + +You can use those to customize the component on both the `sx` prop and the theme. + +{{"demo": "InputVariables.js", "hideToolbar": true}} + +## Accessibility + +In order for the input to be accessible, **it should be linked to a label**. + +The `FormControl` automatically generates a unique id that links the input with the `FormLabel` and `FormHelperText` components: + +{{"demo": "InputField.js"}} + +Alternatively, you can do it manually by targeting the input slot: + +```jsx + + +``` + +## Anatomy + +The Input component is composed of a root `
` with an input `` nested inside. + +```html +
+ +
+``` diff --git a/docs/data/joy/pages.ts b/docs/data/joy/pages.ts index 821a6742308d85..67c3ecf29bbd3f 100644 --- a/docs/data/joy/pages.ts +++ b/docs/data/joy/pages.ts @@ -32,13 +32,14 @@ const pages = [ children: [ { pathname: '/joy-ui/react-autocomplete' }, { pathname: '/joy-ui/react-button' }, - { pathname: '/joy-ui/react-text-field', title: 'Text Field' }, - { pathname: '/joy-ui/react-textarea' }, { pathname: '/joy-ui/react-checkbox' }, + { pathname: '/joy-ui/react-input' }, { pathname: '/joy-ui/react-radio-button', title: 'Radio Group' }, { pathname: '/joy-ui/react-select' }, { pathname: '/joy-ui/react-slider' }, { pathname: '/joy-ui/react-switch' }, + { pathname: '/joy-ui/react-textarea' }, + { pathname: '/joy-ui/react-text-field', title: 'Text Field' }, ], }, { diff --git a/docs/pages/joy-ui/react-input.js b/docs/pages/joy-ui/react-input.js new file mode 100644 index 00000000000000..1f66aa6c7b33a7 --- /dev/null +++ b/docs/pages/joy-ui/react-input.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs/data/joy/components/input/input.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/public/_redirects b/docs/public/_redirects index 1bfcb9283caa02..a141e9c9da8768 100644 --- a/docs/public/_redirects +++ b/docs/public/_redirects @@ -365,6 +365,7 @@ https://v4.material-ui.com/* https://v4.mui.com/:splat 301! /zh/blog/* /blog/:splat 301 /pt/blog/* /blog/:splat 301 /:lang/size-snapshot/ /size-snapshot/ 301 +/joy-ui/react-text-field/ /joy-ui/react-input/ 301 /joy-ui/customization/themed-tokens/ /joy-ui/customization/themed-components/ 301 /:lang/joy-ui/customization/one-off-styling/ /:lang/joy-ui/customization/approaches/#one-off-customization 301 /joy-ui/customization/one-off-styling/ /joy-ui/customization/approaches/#one-off-customization 301 diff --git a/docs/src/modules/components/JoyVariablesDemo.tsx b/docs/src/modules/components/JoyVariablesDemo.tsx index 8ef657dc55ea3e..91dd3e73e5afb3 100644 --- a/docs/src/modules/components/JoyVariablesDemo.tsx +++ b/docs/src/modules/components/JoyVariablesDemo.tsx @@ -4,22 +4,25 @@ import Link from '@mui/joy/Link'; import List from '@mui/joy/List'; import ListDivider from '@mui/joy/ListDivider'; import IconButton from '@mui/joy/IconButton'; -import TextField from '@mui/joy/TextField'; +import FormControl from '@mui/joy/FormControl'; +import FormLabel from '@mui/joy/FormLabel'; +import FormHelperText from '@mui/joy/FormHelperText'; import Typography from '@mui/joy/Typography'; import Sheet from '@mui/joy/Sheet'; import BrandingProvider from 'docs/src/BrandingProvider'; import HighlightedCode from 'docs/src/modules/components/HighlightedCode'; -import { inputClasses } from '@mui/joy/Input'; +import Input, { inputClasses } from '@mui/joy/Input'; import ReplayRoundedIcon from '@mui/icons-material/ReplayRounded'; import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; interface DataItem { var: string; - defaultValue?: string; + defaultValue?: string | number; helperText?: string; + inputAttributes?: React.InputHTMLAttributes; } -function formatSx(sx: { [k: string]: string }) { +function formatSx(sx: { [k: string]: string | number }) { const lines = Object.keys(sx); if (!lines.length) { return ''; @@ -82,11 +85,11 @@ export default function JoyVariablesDemo(props: { componentName: string; childrenAccepted?: boolean; data: Array, { defaultOpen?: boolean } | undefined]>; - renderDemo: (sx: { [k: string]: string }) => React.ReactElement; + renderDemo: (sx: { [k: string]: string | number }) => React.ReactElement; renderCode?: (formattedSx: string) => string; }) { const { componentName, data = [], childrenAccepted = false, renderCode } = props; - const [sx, setSx] = React.useState<{ [k: string]: string }>({}); + const [sx, setSx] = React.useState<{ [k: string]: string | number }>({}); return ( { function renderField(item: DataItem) { const resolvedValue = sx[item.var] || item.defaultValue; + const resolvedInputAttributes = item.inputAttributes || {}; return ( - { - if ((event.ctrlKey || event.metaKey) && event.code === 'KeyZ') { - setSx((prevSx) => { - const newSx = { ...prevSx }; - delete newSx[item.var]; - return newSx; - }); - } - }, - }, - }} - endDecorator={ - - - px - - {sx[item.var] && sx[item.var] !== item.defaultValue && ( - + + {item.var} + { + if ((event.ctrlKey || event.metaKey) && event.code === 'KeyZ') { setSx((prevSx) => { const newSx = { ...prevSx }; delete newSx[item.var]; return newSx; - }) + }); } - > - - - )} - - } - type="number" - onChange={(event) => { - const { value } = event.target; - setSx((prevSx) => { - if (!value) { - const newSx = { ...prevSx }; - // @ts-ignore - delete newSx[item.var]; - return newSx; - } - return { - ...prevSx, - [item.var]: `${value}px`, - }; - }); - }} - sx={{ - minWidth: 0, - flexGrow: 1, - [`& .${inputClasses.root}`]: { '--Input-paddingInline': '0.5rem' }, - [`& .${inputClasses.endDecorator}`]: { alignItems: 'center' }, - }} - /> + }, + ...resolvedInputAttributes, + }, + }} + endDecorator={ + + {typeof resolvedValue === 'string' ? ( + + px + + ) : null} + {sx[item.var] && sx[item.var] !== item.defaultValue ? ( + + setSx((prevSx) => { + const newSx = { ...prevSx }; + delete newSx[item.var]; + return newSx; + }) + } + > + + + ) : null} + + } + type="number" + onChange={(event) => { + const { value } = event.target; + setSx((prevSx) => { + if (!value) { + const newSx = { ...prevSx }; + // @ts-ignore + delete newSx[item.var]; + return newSx; + } + return { + ...prevSx, + [item.var]: + typeof resolvedValue === 'string' ? `${value}px` : Number(value), + }; + }); + }} + sx={{ + minWidth: 0, + flexGrow: 1, + [`& .${inputClasses.root}`]: { '--Input-paddingInline': '0.5rem' }, + [`& .${inputClasses.endDecorator}`]: { alignItems: 'center' }, + }} + /> + {item.helperText} + ); } if (Array.isArray(dataItem)) {