[Glitch] Profile editing: Name and bio

Port ed4787c1b1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
Echo authored and Claire committed 2026-02-19 21:53:24 +01:00
1 parent eebed16f59
commit 3ac5b10dec
16 files changed
+602 -61

No files matched your search

@@ -42,6 +42,13 @@ export const WithError: Story = {
},
};
export const AutoSize: Story = {
args: {
autoSize: true,
defaultValue: 'This textarea will grow as you type more lines.',
},
};
export const Plain: Story = {
render(args) {
return <TextArea {...args} />;
@@ -3,12 +3,16 @@ import { forwardRef, useCallback } from 'react';
import classNames from 'classnames';
import type { TextareaAutosizeProps } from 'react-textarea-autosize';
import TextAreaAutosize from 'react-textarea-autosize';
import { FormFieldWrapper } from './form_field_wrapper';
import type { CommonFieldWrapperProps } from './form_field_wrapper';
import classes from './text_input.module.scss';
interface Props
extends ComponentPropsWithoutRef<'textarea'>, CommonFieldWrapperProps {}
type TextAreaProps =
| ({ autoSize?: false } & ComponentPropsWithoutRef<'textarea'>)
| ({ autoSize: true } & TextareaAutosizeProps);
/**
* A simple form field for multi-line text.
@@ -17,45 +21,56 @@ interface Props
* or optional (by explicitly setting `required={false}`)
*/
export const TextAreaField = forwardRef<HTMLTextAreaElement, Props>(
({ id, label, hint, required, hasError, ...otherProps }, ref) => (
<FormFieldWrapper
label={label}
hint={hint}
required={required}
hasError={hasError}
inputId={id}
>
{(inputProps) => <TextArea {...otherProps} {...inputProps} ref={ref} />}
</FormFieldWrapper>
),
);
export const TextAreaField = forwardRef<
HTMLTextAreaElement,
TextAreaProps & CommonFieldWrapperProps
>(({ id, label, hint, required, hasError, ...otherProps }, ref) => (
<FormFieldWrapper
label={label}
hint={hint}
required={required}
hasError={hasError}
inputId={id}
>
{(inputProps) => <TextArea {...otherProps} {...inputProps} ref={ref} />}
</FormFieldWrapper>
));
TextAreaField.displayName = 'TextAreaField';
export const TextArea = forwardRef<
HTMLTextAreaElement,
ComponentPropsWithoutRef<'textarea'>
>(({ className, onKeyDown, ...otherProps }, ref) => {
const handleSubmitHotkey = useCallback(
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
onKeyDown?.(e);
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
const targetForm = e.currentTarget.form;
targetForm?.requestSubmit();
}
},
[onKeyDown],
);
export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
({ className, onKeyDown, autoSize, ...otherProps }, ref) => {
const handleSubmitHotkey = useCallback(
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
onKeyDown?.(e);
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
const targetForm = e.currentTarget.form;
targetForm?.requestSubmit();
}
},
[onKeyDown],
);
return (
<textarea
{...otherProps}
onKeyDown={handleSubmitHotkey}
className={classNames(className, classes.input)}
ref={ref}
/>
);
});
if (autoSize) {
return (
<TextAreaAutosize
{...(otherProps as TextareaAutosizeProps)}
onKeyDown={handleSubmitHotkey}
className={classNames(className, classes.input)}
ref={ref}
/>
);
}
return (
<textarea
{...otherProps}
onKeyDown={handleSubmitHotkey}
className={classNames(className, classes.input)}
ref={ref}
/>
);
},
);
TextArea.displayName = 'TextArea';