diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/EventTypesWrapper.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/EventTypesWrapper.tsx new file mode 100644 index 0000000000..1ce0d45d5d --- /dev/null +++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/EventTypesWrapper.tsx @@ -0,0 +1,45 @@ +"use client"; + +import { useDebounce } from "@calcom/lib/hooks/useDebounce"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import { ShellMainAppDir } from "app/(use-page-wrapper)/(main-nav)/ShellMainAppDir"; +import type { ReactElement } from "react"; +import { useState } from "react"; + +import EventTypes, { EventTypesCTA, SearchContext } from "~/event-types/views/event-types-listing-view"; + +type GetUserEventGroupsResponse = Parameters[0]["userEventGroupsData"]; + +const CTAWithContext = ({ + userEventGroupsData, +}: { + userEventGroupsData: GetUserEventGroupsResponse; +}): ReactElement => { + return ; +}; + +export function EventTypesWrapper({ + userEventGroupsData, + user, +}: { + userEventGroupsData: GetUserEventGroupsResponse; + user: { + id: number; + completedOnboarding?: boolean; + } | null; +}): ReactElement { + const { t } = useLocale(); + const [searchTerm, setSearchTerm] = useState(""); + const debouncedSearchTerm = useDebounce(searchTerm, 500); + + return ( + + }> + + + + ); +} diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx index e74d324a19..6d2a376017 100644 --- a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx +++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx @@ -1,55 +1,60 @@ -import { ShellMainAppDir } from "app/(use-page-wrapper)/(main-nav)/ShellMainAppDir"; +import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; +import { checkOnboardingRedirect } from "@calcom/features/auth/lib/onboardingUtils"; +import { getTeamsFiltersFromQuery } from "@calcom/features/filters/lib/getTeamsFiltersFromQuery"; +import type { RouterOutputs } from "@calcom/trpc/react"; +import { eventTypesRouter } from "@calcom/trpc/server/routers/viewer/eventTypes/_router"; +import { buildLegacyRequest } from "@lib/buildLegacyCtx"; import { createRouterCaller, getTRPCContext } from "app/_trpc/context"; -import type { PageProps, ReadonlyHeaders, ReadonlyRequestCookies } from "app/_types"; -import { _generateMetadata, getTranslate } from "app/_utils"; +import type { + PageProps, + ReadonlyHeaders, + ReadonlyRequestCookies, +} from "app/_types"; +import { _generateMetadata } from "app/_utils"; import { unstable_cache } from "next/cache"; import { cookies, headers } from "next/headers"; import { redirect } from "next/navigation"; +import type { ReactElement } from "react"; -import { checkOnboardingRedirect } from "@calcom/features/auth/lib/onboardingUtils"; -import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; -import { getTeamsFiltersFromQuery } from "@calcom/features/filters/lib/getTeamsFiltersFromQuery"; -import { eventTypesRouter } from "@calcom/trpc/server/routers/viewer/eventTypes/_router"; +import { EventTypesWrapper } from "./EventTypesWrapper"; -import { buildLegacyRequest } from "@lib/buildLegacyCtx"; - -import EventTypes, { EventTypesCTA } from "~/event-types/views/event-types-listing-view"; - -export const generateMetadata = async () => - await _generateMetadata( - (t) => t("event_types_page_title"), - (t) => t("event_types_page_subtitle"), - undefined, - undefined, - "/event-types" +const getCachedEventGroups: ( + headers: ReadonlyHeaders, + cookies: ReadonlyRequestCookies, + filters?: { + teamIds?: number[] | undefined; + userIds?: number[] | undefined; + upIds?: string[] | undefined; + } +) => Promise = + unstable_cache( + async ( + headers: ReadonlyHeaders, + cookies: ReadonlyRequestCookies, + filters?: { + teamIds?: number[] | undefined; + userIds?: number[] | undefined; + upIds?: string[] | undefined; + } + ): Promise => { + const eventTypesCaller = await createRouterCaller( + eventTypesRouter, + await getTRPCContext(headers, cookies) + ); + return await eventTypesCaller.getUserEventGroups({ filters }); + }, + ["viewer.eventTypes.getUserEventGroups"], + { revalidate: 3600 } // seconds ); -const getCachedEventGroups = unstable_cache( - async ( - headers: ReadonlyHeaders, - cookies: ReadonlyRequestCookies, - filters?: { - teamIds?: number[] | undefined; - userIds?: number[] | undefined; - upIds?: string[] | undefined; - } - ) => { - const eventTypesCaller = await createRouterCaller( - eventTypesRouter, - await getTRPCContext(headers, cookies) - ); - return await eventTypesCaller.getUserEventGroups({ filters }); - }, - ["viewer.eventTypes.getUserEventGroups"], - { revalidate: 3600 } // seconds -); - -const Page = async ({ searchParams }: PageProps) => { +const Page = async ({ searchParams }: PageProps): Promise => { const _searchParams = await searchParams; const _headers = await headers(); const _cookies = await cookies(); - const session = await getServerSession({ req: buildLegacyRequest(_headers, _cookies) }); + const session = await getServerSession({ + req: buildLegacyRequest(_headers, _cookies), + }); if (!session?.user?.id) { return redirect("/auth/login"); } @@ -65,18 +70,30 @@ const Page = async ({ searchParams }: PageProps) => { return redirect(onboardingPath); } - const t = await getTranslate(); const filters = getTeamsFiltersFromQuery(_searchParams); - const userEventGroupsData = await getCachedEventGroups(_headers, _cookies, filters); + const userEventGroupsData = await getCachedEventGroups( + _headers, + _cookies, + filters + ); return ( - }> - - + ); }; +export const generateMetadata = async (): Promise< + ReturnType +> => + await _generateMetadata( + (t) => t("event_types_page_title"), + (t) => t("event_types_page_subtitle"), + undefined, + undefined, + "/event-types" + ); + export default Page; diff --git a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx index 14183339d5..2fbc28afc6 100644 --- a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx +++ b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormEdit.tsx @@ -88,9 +88,16 @@ function Field({ moveUp={moveUp} moveDown={moveDown} badge={ - router ? { text: router.name, variant: "gray", href: `${appUrl}/form-edit/${router.id}` } : null + router + ? { + text: router.name, + variant: "gray", + href: `${appUrl}/form-edit/${router.id}`, + } + : null } - deleteField={router ? null : deleteField}> + deleteField={router ? null : deleteField} + >
@@ -122,12 +141,23 @@ function Field({ { - hookForm.setValue(`${hookFieldNamespace}.identifier`, e.target.value, { shouldDirty: true }); + hookForm.setValue( + `${hookFieldNamespace}.identifier`, + e.target.value, + { shouldDirty: true } + ); }} />
@@ -137,7 +167,9 @@ function Field({ control={hookForm.control} defaultValue={routerField?.type} render={({ field: { value, onChange } }) => { - const defaultValue = FieldTypes.find((fieldType) => fieldType.value === value); + const defaultValue = FieldTypes.find( + (fieldType) => fieldType.value === value + ); if (disableTypeChange) { return (
@@ -150,9 +182,15 @@ function Field({ className={classNames( "h-8 w-full justify-between text-left text-sm", !!router && "bg-subtle cursor-not-allowed" - )}> - {defaultValue?.label || "Select field type"} - + )} + > + + {defaultValue?.label || "Select field type"} + +
@@ -273,7 +311,9 @@ const FormEdit = ({
{hookFormFields.map((field, key) => { - const existingField = Boolean((form.fields || []).find((f) => f.id === field.id)); + const existingField = Boolean( + (form.fields || []).find((f) => f.id === field.id) + ); const hasFormResponses = (form._count?.responses ?? 0) > 0; return ( {hookFormFields.length ? (
-
@@ -319,7 +365,7 @@ const FormEdit = ({ ) : (
{/* TODO: remake empty screen for V3 */} -
+
{/* Icon card - Top */}
@@ -350,7 +396,12 @@ const FormEdit = ({ Fields are the form fields that the booker would see.

-
@@ -370,7 +421,9 @@ export default function FormEditPage({ {...props} appUrl={appUrl} permissions={permissions} - Page={({ hookForm, form }) => } + Page={({ hookForm, form }) => ( + + )} /> ); diff --git a/apps/web/components/dialog/__tests__/EditLocationDialog.test.tsx b/apps/web/components/dialog/__tests__/EditLocationDialog.test.tsx index 1aa1da9f87..84e83a4a1b 100644 --- a/apps/web/components/dialog/__tests__/EditLocationDialog.test.tsx +++ b/apps/web/components/dialog/__tests__/EditLocationDialog.test.tsx @@ -46,8 +46,8 @@ vi.mock("@calcom/features/form/components/LocationSelect", () => { }; }); -const AttendeePhoneNumberLabel = "Attendee Phone Number"; -const OrganizerPhoneLabel = "Organizer Phone Number"; +const AttendeePhoneNumberLabel = "Attendee phone number"; +const OrganizerPhoneLabel = "Organizer phone number"; const CampfireLabel = "Campfire"; const ZoomVideoLabel = "Zoom Video"; const OrganizerDefaultConferencingAppLabel = "Organizer's default app"; diff --git a/apps/web/modules/bookings/components/BookingListContainer.tsx b/apps/web/modules/bookings/components/BookingListContainer.tsx index 6793811152..23e3566267 100644 --- a/apps/web/modules/bookings/components/BookingListContainer.tsx +++ b/apps/web/modules/bookings/components/BookingListContainer.tsx @@ -1,6 +1,10 @@ "use client"; -import { useReactTable, getCoreRowModel, getSortedRowModel } from "@tanstack/react-table"; +import { + useReactTable, + getCoreRowModel, + getSortedRowModel, +} from "@tanstack/react-table"; import { useRouter } from "next/navigation"; import React, { useState, useMemo, useEffect, useCallback } from "react"; @@ -31,7 +35,11 @@ import { BookingDetailsSheetStoreProvider, useBookingDetailsSheetStore, } from "../store/bookingDetailsSheetStore"; -import type { RowData, BookingListingStatus, BookingsGetOutput } from "../types"; +import type { + RowData, + BookingListingStatus, + BookingsGetOutput, +} from "../types"; import { BookingDetailsSheet } from "./BookingDetailsSheet"; import { BookingList } from "./BookingList"; import { ViewToggleButton } from "./ViewToggleButton"; @@ -42,7 +50,11 @@ interface FilterButtonProps { setShowFilters: (value: boolean | ((prev: boolean) => boolean)) => void; } -function FilterButton({ table, displayedFilterCount, setShowFilters }: FilterButtonProps) { +function FilterButton({ + table, + displayedFilterCount, + setShowFilters, +}: FilterButtonProps) { const { t } = useLocale(); if (displayedFilterCount === 0) { @@ -55,7 +67,8 @@ function FilterButton({ table, displayedFilterCount, setShowFilters }: FilterBut StartIcon="list-filter" className="h-full" size="sm" - onClick={() => setShowFilters((value) => !value)}> + onClick={() => setShowFilters((value) => !value)} + > {t("filter")} {displayedFilterCount} @@ -96,7 +109,9 @@ function BookingListInner({ }: BookingListInnerProps) { const { t } = useLocale(); const user = useMeQuery().data; - const setSelectedBookingUid = useBookingDetailsSheetStore((state) => state.setSelectedBookingUid); + const setSelectedBookingUid = useBookingDetailsSheetStore( + (state) => state.setSelectedBookingUid + ); const router = useRouter(); const [showFilters, setShowFilters] = useState(true); @@ -104,7 +119,11 @@ function BookingListInner({ useListAutoSelector(bookings); const ErrorView = errorMessage ? ( - + ) : undefined; const handleBookingClick = useCallback( @@ -122,7 +141,11 @@ function BookingListInner({ handleBookingClick, }); - const finalData = useBookingListData({ data, status, userTimeZone: user?.timeZone }); + const finalData = useBookingListData({ + data, + status, + userTimeZone: user?.timeZone, + }); const getFacetedUniqueValues = useFacetedUniqueValues(); @@ -167,7 +190,9 @@ function BookingListInner({ value={currentTab} onValueChange={(value) => { if (!value) return; - const selectedTab = tabOptions.find((tab) => tab.value === value); + const selectedTab = tabOptions.find( + (tab) => tab.value === value + ); if (selectedTab?.href) { router.push(selectedTab.href); } @@ -187,8 +212,10 @@ function BookingListInner({ {/* Desktop: auto-pushed to right via flex-grow spacer, Mobile: continue on second row */}
- - {bookingsV3Enabled && } + + {bookingsV3Enabled && ( + + )}
{displayedFilterCount > 0 && showFilters && (
@@ -203,7 +230,11 @@ function BookingListInner({
)} {status === "upcoming" && !isEmpty && ( - + )}
query.data?.bookings ?? [], [query.data?.bookings]); + const bookings = useMemo( + () => query.data?.bookings ?? [], + [query.data?.bookings] + ); // Always call the hook and provide navigation capabilities // The BookingDetailsSheet is only rendered when bookingsV3Enabled is true (see line 212) @@ -285,7 +330,10 @@ export function BookingListContainer(props: BookingListContainerProps) { }); return ( - + { + if (!isPending && orgBranding && currentOrganisation) { + window.scrollTo(0, 0); + } + }, [isPending, orgBranding, currentOrganisation]); + if (isPending || !orgBranding || !currentOrganisation) { return ; } @@ -126,7 +136,8 @@ const OrgProfileView = ({ calVideoLogo: currentOrganisation?.calVideoLogo || "", slug: currentOrganisation?.slug || - ((currentOrganisation?.metadata as Prisma.JsonObject)?.requestedSlug as string) || + ((currentOrganisation?.metadata as Prisma.JsonObject) + ?.requestedSlug as string) || "", }; @@ -142,15 +153,18 @@ const OrgProfileView = ({
- -

{currentOrganisation?.name}

+ +

+ {currentOrganisation?.name} +

{!isBioEmpty && ( <>
{ navigator.clipboard.writeText(orgBranding.fullDomain); showToast("Copied to clipboard", "success"); - }}> + }} + > {t("copy_link_org")}
@@ -189,7 +204,10 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => { const mutation = trpc.viewer.organizations.update.useMutation({ onError: (err) => { // Handle JSON parsing errors from body size limit exceeded - if (err.message.includes("Unexpected token") && err.message.includes("Body excee")) { + if ( + err.message.includes("Unexpected token") && + err.message.includes("Body excee") + ) { showToast(t("converted_image_size_limit_exceed"), "error"); return; } @@ -239,40 +257,87 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => { }; mutation.mutate(variables); - }}> + }} + >
-
+
{ const showRemoveLogoButton = value !== null; return ( - <> +
-
+
{showRemoveLogoButton && ( - )}
- +
+ ); + }} + /> + { + const showRemoveLogoButton = !!value; + return ( +
+ + } + size="lg" + /> +
+
+ + {showRemoveLogoButton && ( + + )} +
+
+
); }} /> @@ -291,67 +356,72 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => { data-testid="profile-upload-banner" alt={`${defaultValues.name} Banner` || ""} className="grid min-h-[150px] w-full place-items-center rounded-md sm:min-h-[200px]" - fallback={t("no_target", { target: "banner" })} + fallback={ + !value ? ( +
+

+ {t("no_target", { target: "banner" })} +

+
+
+ +
+ ) : ( + t("no_target", { target: "banner" }) + ) + } imageSrc={value} /> -
-
-
- - ); - }} - /> -
-
- { - const showRemoveLogoButton = !!value; - return ( - <> - } - size="lg" - /> -
-
- - {showRemoveLogoButton && ( - - )} -
-
+ )} ); }} @@ -406,7 +476,8 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => { size="sm" type="button" aria-label="copy organization id" - onClick={() => handleCopy(value.toString())}> + onClick={() => handleCopy(value.toString())} + > @@ -419,7 +490,9 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => { md.render(form.getValues("bio") || "")} - setText={(value: string) => form.setValue("bio", turndown(value), { shouldDirty: true })} + setText={(value: string) => + form.setValue("bio", turndown(value), { shouldDirty: true }) + } excludedToolbarItems={["blockType"]} disableLists firstRender={firstRender} @@ -435,7 +508,8 @@ const OrgProfileForm = ({ defaultValues }: { defaultValues: FormValues }) => { color="primary" type="submit" loading={mutation.isPending} - disabled={isDisabled}> + disabled={isDisabled} + > {t("update")} diff --git a/apps/web/modules/ee/teams/components/EditMemberSheet.tsx b/apps/web/modules/ee/teams/components/EditMemberSheet.tsx index 5b6aea0fb5..e7050a43c4 100644 --- a/apps/web/modules/ee/teams/components/EditMemberSheet.tsx +++ b/apps/web/modules/ee/teams/components/EditMemberSheet.tsx @@ -12,7 +12,13 @@ import { Avatar } from "@calcom/ui/components/avatar"; import { Form } from "@calcom/ui/components/form"; import { ToggleGroup, Select } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; -import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetBody } from "@calcom/ui/components/sheet"; +import { + Sheet, + SheetContent, + SheetFooter, + SheetHeader, + SheetBody, +} from "@calcom/ui/components/sheet"; import { Skeleton, Loader } from "@calcom/ui/components/skeleton"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; @@ -50,7 +56,9 @@ export function EditMemberSheet({ (state) => [state.editMode, state.setEditMode, state.setMutationLoading], shallow ); - const [role, setRole] = useState(selectedUser.customRoleId || selectedUser.role); + const [role, setRole] = useState( + selectedUser.customRoleId || selectedUser.role + ); const name = selectedUser.name || (() => { @@ -61,16 +69,19 @@ export function EditMemberSheet({ const bookerUrl = selectedUser.bookerUrl; const utils = trpc.useUtils(); const bookerUrlWithoutProtocol = bookerUrl.replace(/^https?:\/\//, ""); - const bookingLink = selectedUser.username ? `${bookerUrlWithoutProtocol}/${selectedUser.username}` : ""; + const bookingLink = selectedUser.username + ? `${bookerUrlWithoutProtocol}/${selectedUser.username}` + : ""; // Load custom roles for the team - const { data: customRoles, isPending: isLoadingRoles } = trpc.viewer.pbac.getTeamRoles.useQuery( - { teamId }, - { - enabled: !!teamId, - retry: false, // Don't retry if PBAC is not enabled - } - ); + const { data: customRoles, isPending: isLoadingRoles } = + trpc.viewer.pbac.getTeamRoles.useQuery( + { teamId }, + { + enabled: !!teamId, + retry: false, // Don't retry if PBAC is not enabled + } + ); const options = useMemo(() => { // If we have custom roles, only show custom roles @@ -95,7 +106,10 @@ export function EditMemberSheet({ label: t("owner"), value: MembershipRole.OWNER, }, - ].filter(({ value }) => value !== MembershipRole.OWNER || currentMember === MembershipRole.OWNER); + ].filter( + ({ value }) => + value !== MembershipRole.OWNER || currentMember === MembershipRole.OWNER + ); }, [t, currentMember, customRoles]); // Determine if we should use Select (when custom roles exist) or ToggleGroup (traditional only) @@ -109,10 +123,11 @@ export function EditMemberSheet({ }, }); - const { data: getUserConnectedApps, isPending } = trpc.viewer.teams.getUserConnectedApps.useQuery({ - userIds: [selectedUser.id], - teamId, - }); + const { data: getUserConnectedApps, isPending } = + trpc.viewer.teams.getUserConnectedApps.useQuery({ + userIds: [selectedUser.id], + teamId, + }); const connectedApps = getUserConnectedApps?.[selectedUser.id]; @@ -191,21 +206,32 @@ export function EditMemberSheet({ onOpenChange={() => { setEditMode(false); dispatch({ type: "CLOSE_MODAL" }); - }}> + }} + > {!isPending && !isLoadingRoles ? ( -
+ -
+
- +

@@ -214,16 +240,28 @@ export function EditMemberSheet({

- {selectedUser.bio ? selectedUser?.bio : t("user_has_no_bio")} + {selectedUser.bio + ? selectedUser?.bio + : t("user_has_no_bio")}

-

{t("profile")}

- - +

+ {t("profile")} +

+ + {!editMode ? ( {shouldUseSelect ? ( { @@ -1075,7 +1211,12 @@ const EmbedTypeCodeAndPreviewDialogContent = ({ />
-
+
Button color
-
+
Text color
setIsBookingCustomizationOpen((val) => !val)}> + onOpenChange={() => + setIsBookingCustomizationOpen((val) => !val) + } + >
{/* Conditionally render EmbedTheme only if NOT React Atom */} {embedParams.embedTabName !== EmbedTabName.ATOM_REACT && (
); -export const InputField = forwardRef(function InputField(props, ref) { - const id = useId(); - const { t: _t, isLocaleReady, i18n } = useLocale(); - const t = props.t || _t; - const name = props.name || ""; - const { - label = t(name), - labelProps, - labelClassName, - disabled, - LockedIcon, - placeholder = isLocaleReady && i18n.exists(`${name}_placeholder`) ? t(`${name}_placeholder`) : "", - className, - addOnLeading, - addOnSuffix, - addOnClassname, - inputIsFullWidth, - hint, - type, - hintErrors, - labelSrOnly, - noLabel, - containerClassName, - readOnly, - showAsteriskIndicator, - onClickAddon, +export const InputField = forwardRef( + function InputField(props, ref) { + const id = useId(); + const { t: _t, isLocaleReady, i18n } = useLocale(); + const t = props.t || _t; + const name = props.name || ""; + const { + label = t(name), + labelProps, + labelClassName, + disabled, + LockedIcon, + placeholder = isLocaleReady && i18n.exists(`${name}_placeholder`) + ? t(`${name}_placeholder`) + : "", + className, + addOnLeading, + addOnSuffix, + addOnClassname, + inputIsFullWidth, + hint, + type, + hintErrors, + labelSrOnly, + noLabel, + containerClassName, + readOnly, + showAsteriskIndicator, + onClickAddon, - t: __t, - dataTestid, - size, - ...passThrough - } = props; + t: __t, + dataTestid, + size, + ...passThrough + } = props; - const [inputValue, setInputValue] = useState(""); + const [inputValue, setInputValue] = useState(""); - const handleFocusInput = (e: React.MouseEvent) => { - e.currentTarget.parentElement?.querySelector("input")?.focus(); - }; + const handleFocusInput = (e: React.MouseEvent) => { + e.currentTarget.parentElement?.querySelector("input")?.focus(); + }; - return ( -
- {!!name && !noLabel && ( - - )} - {addOnLeading || addOnSuffix ? ( -
- {addOnLeading && ( - - {addOnLeading} - - )} - + {!!name && !noLabel && ( + + )} + {addOnLeading || addOnSuffix ? ( +
+ {addOnLeading && ( + + {addOnLeading} + + )} + { + setInputValue(e.target.value); + props.onChange?.(e); + }, + value: inputValue, + })} + disabled={readOnly || disabled} + ref={ref} + /> + {addOnSuffix && ( + { + handleFocusInput(e); + onClickAddon?.(e); + }} + className={classNames(addOnClassname)} + > + {addOnSuffix} + + )} + {type === "search" && inputValue?.toString().length > 0 && ( + { + setInputValue(""); + props.onChange?.( + e as unknown as React.ChangeEvent + ); + }} + /> + )} +
+ ) : ( + { - setInputValue(e.target.value); - props.onChange?.(e); - }, - value: inputValue, - })} - disabled={readOnly || disabled} + readOnly={readOnly} ref={ref} + isFullWidth={inputIsFullWidth} + disabled={readOnly || disabled} /> - {addOnSuffix && ( - { - handleFocusInput(e); - onClickAddon?.(e); - }} - className={classNames(addOnClassname)}> - {addOnSuffix} - - )} - {type === "search" && inputValue?.toString().length > 0 && ( - { - setInputValue(""); - props.onChange?.(e as unknown as React.ChangeEvent); - }} - /> - )} -
- ) : ( - - )} - - {hint &&
{hint}
} -
- ); -}); + )} + + {hint && ( +
+ + {hint} +
+ )} +
+ ); + } +); -export const TextField = forwardRef(function TextField(props, ref) { - return ; -}); +export const TextField = forwardRef( + function TextField(props, ref) { + return ; + } +);