@@ -11,17 +11,21 @@ import {
1111import { copySmall } from '@wordpress/icons' ;
1212import { useCopyToClipboard , useInstanceId } from '@wordpress/compose' ;
1313import { useDispatch } from '@wordpress/data' ;
14- import { useCallback , useEffect , useRef } from '@wordpress/element' ;
14+ import { useCallback , useEffect , useRef , useState } from '@wordpress/element' ;
1515import { store as noticesStore } from '@wordpress/notices' ;
1616import { safeDecodeURIComponent } from '@wordpress/url' ;
1717import type { DataFormControlProps } from '@wordpress/dataviews' ;
1818import { __ } from '@wordpress/i18n' ;
1919
20+ /**
21+ * External dependencies
22+ */
23+ import clsx from 'clsx' ;
24+
2025/**
2126 * Internal dependencies
2227 */
2328import type { BasePost } from '../../types' ;
24- import { getSlug } from './utils' ;
2529
2630const SlugEdit = ( {
2731 field,
@@ -30,7 +34,10 @@ const SlugEdit = ( {
3034} : DataFormControlProps < BasePost > ) => {
3135 const { id } = field ;
3236
33- const slug = field . getValue ( { item : data } ) || getSlug ( data ) ;
37+ const slug = field . getValue ( { item : data } ) ;
38+
39+ const [ isValid , setIsValid ] = useState ( true ) ;
40+
3441 const permalinkTemplate = data . permalink_template || '' ;
3542 const PERMALINK_POSTNAME_REGEX = / % (?: p o s t n a m e | p a g e n a m e ) % / ;
3643 const [ prefix , suffix ] = permalinkTemplate . split (
@@ -40,7 +47,7 @@ const SlugEdit = ( {
4047 const permalinkSuffix = suffix ;
4148 const isEditable = PERMALINK_POSTNAME_REGEX . test ( permalinkTemplate ) ;
4249 const originalSlugRef = useRef ( slug ) ;
43- const slugToDisplay = slug || originalSlugRef . current ;
50+ const slugToDisplay = slug ;
4451 const permalink = isEditable
4552 ? `${ permalinkPrefix } ${ slugToDisplay } ${ permalinkSuffix } `
4653 : safeDecodeURIComponent ( data . link || '' ) ;
@@ -52,11 +59,13 @@ const SlugEdit = ( {
5259 } , [ slug ] ) ;
5360
5461 const onChangeControl = useCallback (
55- ( newValue ?: string ) =>
62+ ( newValue ?: string ) => {
63+ setIsValid ( field . isValid ( newValue ?? '' ) ) ;
5664 onChange ( {
5765 [ id ] : newValue ,
58- } ) ,
59- [ id , onChange ]
66+ } ) ;
67+ } ,
68+ [ field , id , onChange ]
6069 ) ;
6170
6271 const { createNotice } = useDispatch ( noticesStore ) ;
@@ -106,7 +115,9 @@ const SlugEdit = ( {
106115 autoComplete = "off"
107116 spellCheck = "false"
108117 type = "text"
109- className = "fields-controls__slug-input"
118+ className = { clsx ( 'fields-controls__slug-input' , {
119+ 'fields-controls__slug-input--invalid' : ! isValid ,
120+ } ) }
110121 onChange = { ( newValue ?: string ) => {
111122 onChangeControl ( newValue ) ;
112123 } }
@@ -117,6 +128,11 @@ const SlugEdit = ( {
117128 } }
118129 aria-describedby = { postUrlSlugDescriptionId }
119130 />
131+ { ! isValid && (
132+ < div className = "fields-controls__slug-error" >
133+ < span > { __ ( 'The slug is invalid.' ) } </ span >
134+ </ div >
135+ ) }
120136 < div className = "fields-controls__slug-help" >
121137 < span className = "fields-controls__slug-help-visual-label" >
122138 { __ ( 'Permalink:' ) }
0 commit comments