SoapboxConfig: refactor Textarea

This commit is contained in:
Alex Gleason 2022-05-05 17:45:32 -05:00
parent df714f1112
commit 874ae980e6
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 23 additions and 18 deletions

View file

@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
interface IFormGroup { interface IFormGroup {
/** Input label message. */ /** Input label message. */
labelText: React.ReactNode, labelText?: React.ReactNode,
/** Input hint message. */ /** Input hint message. */
hintText?: React.ReactNode, hintText?: React.ReactNode,
/** Input errors. */ /** Input errors. */
@ -26,13 +26,15 @@ const FormGroup: React.FC<IFormGroup> = (props) => {
return ( return (
<div> <div>
<label {labelText && (
htmlFor={formFieldId} <label
data-testid='form-group-label' htmlFor={formFieldId}
className='block text-sm font-medium text-gray-700 dark:text-gray-400' data-testid='form-group-label'
> className='block text-sm font-medium text-gray-700 dark:text-gray-400'
{labelText} >
</label> {labelText}
</label>
)}
<div className='mt-1 dark:text-white'> <div className='mt-1 dark:text-white'>
{firstChild} {firstChild}
@ -47,11 +49,11 @@ const FormGroup: React.FC<IFormGroup> = (props) => {
</p> </p>
)} )}
{hintText ? ( {hintText && (
<p data-testid='form-group-hint' className='mt-0.5 text-xs text-gray-400'> <p data-testid='form-group-hint' className='mt-0.5 text-xs text-gray-400'>
{hintText} {hintText}
</p> </p>
) : null} )}
</div> </div>
</div> </div>
); );

View file

@ -1,7 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
interface ITextarea extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'maxLength' | 'onChange' | 'required' | 'disabled'> { interface ITextarea extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'maxLength' | 'onChange' | 'required' | 'disabled' | 'rows'> {
/** Put the cursor into the input on mount. */ /** Put the cursor into the input on mount. */
autoFocus?: boolean, autoFocus?: boolean,
/** The initial text in the input. */ /** The initial text in the input. */
@ -16,11 +16,13 @@ interface ITextarea extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaElemen
value?: string, value?: string,
/** Whether the device should autocomplete text in this textarea. */ /** Whether the device should autocomplete text in this textarea. */
autoComplete?: string, autoComplete?: string,
/** Whether to display the textarea in red. */
hasError?: boolean,
} }
/** Textarea with custom styles. */ /** Textarea with custom styles. */
const Textarea = React.forwardRef( const Textarea = React.forwardRef(
({ isCodeEditor = false, ...props }: ITextarea, ref: React.ForwardedRef<HTMLTextAreaElement>) => { ({ isCodeEditor = false, hasError = false, ...props }: ITextarea, ref: React.ForwardedRef<HTMLTextAreaElement>) => {
return ( return (
<textarea <textarea
{...props} {...props}
@ -29,6 +31,7 @@ const Textarea = React.forwardRef(
'dark:bg-slate-800 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-600 rounded-md': 'dark:bg-slate-800 shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-600 rounded-md':
true, true,
'font-mono': isCodeEditor, 'font-mono': isCodeEditor,
'text-red-600 border-red-600': hasError,
})} })}
/> />
); );

View file

@ -5,12 +5,11 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { updateConfig } from 'soapbox/actions/admin'; import { updateConfig } from 'soapbox/actions/admin';
import { uploadMedia } from 'soapbox/actions/media'; import { uploadMedia } from 'soapbox/actions/media';
import snackbar from 'soapbox/actions/snackbar'; import snackbar from 'soapbox/actions/snackbar';
import { Column, Form, FormActions, FormGroup, Input, Button } from 'soapbox/components/ui'; import { Column, Form, FormActions, FormGroup, Input, Textarea, Button } from 'soapbox/components/ui';
import HStack from 'soapbox/components/ui/hstack/hstack'; import HStack from 'soapbox/components/ui/hstack/hstack';
import Stack from 'soapbox/components/ui/stack/stack'; import Stack from 'soapbox/components/ui/stack/stack';
import Streamfield from 'soapbox/components/ui/streamfield/streamfield'; import Streamfield from 'soapbox/components/ui/streamfield/streamfield';
import { import {
SimpleTextarea,
FileChooserLogo, FileChooserLogo,
Checkbox, Checkbox,
} from 'soapbox/features/forms'; } from 'soapbox/features/forms';
@ -320,14 +319,15 @@ const SoapboxConfig: React.FC = () => {
expanded={jsonEditorExpanded} expanded={jsonEditorExpanded}
onToggle={toggleJSONEditor} onToggle={toggleJSONEditor}
> >
<div className={jsonValid ? 'code-editor' : 'code-editor code-editor--invalid'}> <FormGroup hintText={intl.formatMessage(messages.rawJSONHint)}>
<SimpleTextarea <Textarea
hint={intl.formatMessage(messages.rawJSONHint)}
value={rawJSON} value={rawJSON}
onChange={handleEditJSON} onChange={handleEditJSON}
hasError={!jsonValid}
isCodeEditor
rows={12} rows={12}
/> />
</div> </FormGroup>
</Accordion> </Accordion>
</fieldset> </fieldset>
<FormActions> <FormActions>