Add a dedicated TextField component

This commit is contained in:
2025-09-05 21:04:45 +03:00
Unverified
parent 0cd76af33e
commit 420bad2405
10 changed files with 38 additions and 31 deletions
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
import type { Message } from "../../../core/types";
import { MaterialDialog } from "../Dialog";
import { MaterialDialog } from "../core/Dialog";
interface EditMessageDialogProps {
isOpen: boolean;
@@ -1,6 +1,7 @@
import { useState, useEffect } from "react";
import type { Message } from "../../../core/types";
import { MaterialDialog } from "../Dialog";
import { MaterialDialog } from "../core/Dialog";
import { MaterialTextField } from "../core/TextField";
interface ReplyMessageDialogProps {
isOpen: boolean;
@@ -42,14 +43,13 @@ export function ReplyMessageDialog({ isOpen, onOpenChange, replyToMessage, onSen
<span className="reply-text">{replyToMessage.content}</span>
</div>
</div>
<mdui-text-field
<MaterialTextField
value={replyContent}
onInput={(e) => setReplyContent((e.target as HTMLInputElement).value)}
label="Reply"
variant="outlined"
placeholder="Type your reply..."
maxlength={1000}>
</mdui-text-field>
maxlength={1000} />
<div className="dialog-actions">
<mdui-button onClick={handleCancel} variant="outlined">Cancel</mdui-button>
<mdui-button onClick={handleSendReply}>Send Reply</mdui-button>
@@ -1,6 +1,6 @@
import type { DialogProps } from "../../../core/types";
import type { UserProfile } from "../../../core/types";
import { MaterialDialog } from "../Dialog";
import { MaterialDialog } from "../core/Dialog";
import { formatTime } from "../../../utils/utils";
import defaultAvatar from "../../../resources/images/default-avatar.png";
@@ -1,7 +1,7 @@
import type { Dialog as MduiDialog } from "mdui/components/dialog";
import React, { useEffect, useRef } from "react"
import { createPortal } from "react-dom";
import { id } from "../../utils/utils";
import { id } from "../../../utils/utils";
export interface BaseDialogProps {
onOpenChange: (value: boolean) => void;
@@ -0,0 +1,9 @@
import type { TextField } from "mdui/components/text-field";
type TextFieldProps = React.ComponentPropsWithoutRef<"mdui-text-field">
export function MaterialTextField(props: TextFieldProps & { ref?: React.Ref<TextField> }) {
return <mdui-text-field
autocomplete="off"
{...(props as TextFieldProps & { ref?: React.Ref<HTMLElement> })} />
}
@@ -2,9 +2,10 @@ import { useState, useEffect, useRef, type FormEvent } from "react";
import defaultAvatar from "../../../resources/images/default-avatar.png";
import type { TextField } from "mdui/components/text-field";
import type { DialogProps } from "../../../core/types";
import { MaterialDialog } from "../Dialog";
import { MaterialDialog } from "../core/Dialog";
import { useProfile } from "../../hooks/useProfile";
import { ImageCropper } from "./ImageCropper";
import { MaterialTextField } from "../core/TextField";
export function ProfileDialog({ isOpen, onOpenChange }: DialogProps) {
const { profileData, isLoading, isUpdating, updateProfileData, uploadProfilePictureData } = useProfile();
@@ -109,19 +110,18 @@ export function ProfileDialog({ isOpen, onOpenChange }: DialogProps) {
onChange={handleImageSelect}
/>
</div>
<mdui-text-field
<MaterialTextField
id="username-field"
label="Имя пользователя"
variant="outlined"
value={username}
onChange={(e: FormEvent<HTMLElement & TextField>) => setUsername((e.target as TextField).value)}
autocomplete="username"
disabled={isLoading || isUpdating}
/>
disabled={isLoading || isUpdating} />
</div>
<form id="profile-form" onSubmit={handleSubmit}>
<mdui-text-field
<MaterialTextField
id="description-field"
label="О себе"
variant="outlined"
@@ -129,8 +129,7 @@ export function ProfileDialog({ isOpen, onOpenChange }: DialogProps) {
onChange={(e: FormEvent<HTMLElement & TextField>) => setDescription((e.target as TextField).value)}
placeholder="Расскажите о себе..."
autocomplete="none"
disabled={isLoading || isUpdating}
/>
disabled={isLoading || isUpdating} />
<div className="dialog-actions">
<mdui-button
type="submit"
@@ -1,7 +1,7 @@
import { useState } from "react";
import { PRODUCT_NAME } from "../../../core/config";
import type { DialogProps } from "../../../core/types";
import { MaterialDialog } from "../Dialog";
import { MaterialDialog } from "../core/Dialog";
export function SettingsDialog({ isOpen, onOpenChange }: DialogProps) {
const [activePanel, setActivePanel] = useState("notifications-settings");