From c908dcd5f782be53e172ddbd4fd9bb8234a1321e Mon Sep 17 00:00:00 2001 From: Miroslav Mitev Date: Thu, 25 Sep 2025 18:24:10 +0300 Subject: [PATCH 1/5] Fix glue records validation message by switching to `ValidatedInputControl` --- .../domains/domain-glue-records/form.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/client/dashboard/domains/domain-glue-records/form.tsx b/client/dashboard/domains/domain-glue-records/form.tsx index 401c8ddb5893..09664e199fec 100644 --- a/client/dashboard/domains/domain-glue-records/form.tsx +++ b/client/dashboard/domains/domain-glue-records/form.tsx @@ -2,19 +2,26 @@ import { Card, CardBody, __experimentalVStack as VStack, - __experimentalInputControl as InputControl, __experimentalInputControlSuffixWrapper as InputControlSuffixWrapper, Button, + privateApis, } from '@wordpress/components'; import { DataForm, isItemValid } from '@wordpress/dataviews'; import { useState, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; import { ButtonStack } from '../../components/button-stack'; import { Text } from '../../components/text'; import { isValidIpAddress, isValidNameServerSubdomain } from '../../utils/domain'; import type { DomainGlueRecord } from '@automattic/api-core'; import type { Field } from '@wordpress/dataviews'; +const { unlock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', + '@wordpress/components' +); +const { ValidatedInputControl } = unlock( privateApis ); + export interface FormData { nameServer: string; ipAddress: string; @@ -61,17 +68,20 @@ export default function DomainGlueRecordsForm( { const { id, getValue } = field; const suffix = `.${ domainName }`; const value = getValue( { item: data } ).replace( suffix, '' ); + const validationMessage = field.isValid?.custom?.( { nameServer: value } ); return ( - // TODO: Show the error via Data Form when the ValidatedInputControl component is ready. - { return onChange( { [ id ]: value + suffix } ); } } + customValidity={ + validationMessage ? { type: 'invalid', message: validationMessage } : undefined + } suffix={ { suffix } From 89487eff902317ecbb7db1801098ca5c7017b64f Mon Sep 17 00:00:00 2001 From: Miroslav Mitev Date: Thu, 25 Sep 2025 18:27:30 +0300 Subject: [PATCH 2/5] Fix suffix looking bad for long domain names --- client/dashboard/domains/domain-glue-records/form.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/dashboard/domains/domain-glue-records/form.tsx b/client/dashboard/domains/domain-glue-records/form.tsx index 09664e199fec..541938305a62 100644 --- a/client/dashboard/domains/domain-glue-records/form.tsx +++ b/client/dashboard/domains/domain-glue-records/form.tsx @@ -84,7 +84,9 @@ export default function DomainGlueRecordsForm( { } suffix={ - { suffix } + + { suffix } + } /> From 29029d72386eb19e81b448f6d1f049e5ac8cc497 Mon Sep 17 00:00:00 2001 From: Miroslav Mitev Date: Thu, 25 Sep 2025 18:50:05 +0300 Subject: [PATCH 3/5] Fix type issues --- client/dashboard/domains/domain-glue-records/form.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/dashboard/domains/domain-glue-records/form.tsx b/client/dashboard/domains/domain-glue-records/form.tsx index 541938305a62..97f9b859f76f 100644 --- a/client/dashboard/domains/domain-glue-records/form.tsx +++ b/client/dashboard/domains/domain-glue-records/form.tsx @@ -68,7 +68,7 @@ export default function DomainGlueRecordsForm( { const { id, getValue } = field; const suffix = `.${ domainName }`; const value = getValue( { item: data } ).replace( suffix, '' ); - const validationMessage = field.isValid?.custom?.( { nameServer: value } ); + const validationMessage = field.isValid?.custom?.( data, field ); return ( { + onChange={ ( value: string ) => { return onChange( { [ id ]: value + suffix } ); } } customValidity={ @@ -84,7 +84,7 @@ export default function DomainGlueRecordsForm( { } suffix={ - + { suffix } From db5a7d480dbf33cd74541e5c44e478a9165dd6c9 Mon Sep 17 00:00:00 2001 From: Miroslav Mitev Date: Fri, 26 Sep 2025 16:23:19 +0300 Subject: [PATCH 4/5] Update and use the `SuffixInputControl` component for the input --- .../input-control/suffix-input-control.tsx | 22 ++++++++++++--- .../domains/domain-glue-records/form.tsx | 28 +++---------------- .../site-change-address-modal/content.tsx | 3 +- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/client/dashboard/components/input-control/suffix-input-control.tsx b/client/dashboard/components/input-control/suffix-input-control.tsx index 82971a49512d..593905356190 100644 --- a/client/dashboard/components/input-control/suffix-input-control.tsx +++ b/client/dashboard/components/input-control/suffix-input-control.tsx @@ -1,17 +1,31 @@ import { - __experimentalInputControl as InputControl, __experimentalInputControlSuffixWrapper as InputControlSuffixWrapper, + privateApis, } from '@wordpress/components'; +import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; +import { Text } from '../../components/text'; import type React from 'react'; +const { unlock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', + '@wordpress/components' +); +const { ValidatedInputControl } = unlock( privateApis ); + export default function SuffixInputControl( { suffix, ...props -}: React.ComponentProps< typeof InputControl > ) { +}: React.ComponentProps< typeof ValidatedInputControl > ) { return ( - { suffix } } + suffix={ + + + { suffix } + + + } /> ); } diff --git a/client/dashboard/domains/domain-glue-records/form.tsx b/client/dashboard/domains/domain-glue-records/form.tsx index 97f9b859f76f..5611a6e7ce55 100644 --- a/client/dashboard/domains/domain-glue-records/form.tsx +++ b/client/dashboard/domains/domain-glue-records/form.tsx @@ -1,27 +1,13 @@ -import { - Card, - CardBody, - __experimentalVStack as VStack, - __experimentalInputControlSuffixWrapper as InputControlSuffixWrapper, - Button, - privateApis, -} from '@wordpress/components'; +import { Card, CardBody, __experimentalVStack as VStack, Button } from '@wordpress/components'; import { DataForm, isItemValid } from '@wordpress/dataviews'; import { useState, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; import { ButtonStack } from '../../components/button-stack'; -import { Text } from '../../components/text'; +import SuffixInputControl from '../../components/input-control/suffix-input-control'; import { isValidIpAddress, isValidNameServerSubdomain } from '../../utils/domain'; import type { DomainGlueRecord } from '@automattic/api-core'; import type { Field } from '@wordpress/dataviews'; -const { unlock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules( - 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', - '@wordpress/components' -); -const { ValidatedInputControl } = unlock( privateApis ); - export interface FormData { nameServer: string; ipAddress: string; @@ -71,7 +57,7 @@ export default function DomainGlueRecordsForm( { const validationMessage = field.isValid?.custom?.( data, field ); return ( - - - { suffix } - - - } + suffix={ suffix } /> ); }, diff --git a/client/dashboard/sites/site-change-address-modal/content.tsx b/client/dashboard/sites/site-change-address-modal/content.tsx index afc4db13ae10..217be09a7166 100644 --- a/client/dashboard/sites/site-change-address-modal/content.tsx +++ b/client/dashboard/sites/site-change-address-modal/content.tsx @@ -45,8 +45,7 @@ const SubdomainInputControlEdit = < Item, >( { { DOMAIN_SUFFIX } } + suffix={ DOMAIN_SUFFIX } onChange={ ( newValue ) => { onChange( { [ id ]: newValue } as Partial< Item > ); } } From 6a9e82703d66c3d0fd39352da04f14a7b3d754d2 Mon Sep 17 00:00:00 2001 From: Miroslav Mitev Date: Wed, 1 Oct 2025 16:04:01 +0300 Subject: [PATCH 5/5] Fix type --- client/dashboard/sites/site-change-address-modal/content.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/dashboard/sites/site-change-address-modal/content.tsx b/client/dashboard/sites/site-change-address-modal/content.tsx index 217be09a7166..9aeac903261b 100644 --- a/client/dashboard/sites/site-change-address-modal/content.tsx +++ b/client/dashboard/sites/site-change-address-modal/content.tsx @@ -46,7 +46,7 @@ const SubdomainInputControlEdit = < Item, >( { label={ field.label } value={ getValue( { item: data } ) } suffix={ DOMAIN_SUFFIX } - onChange={ ( newValue ) => { + onChange={ ( newValue: string ) => { onChange( { [ id ]: newValue } as Partial< Item > ); } } />