-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
QuickEdit: Add slug field control (#65196)
Co-authored-by: gigitux <gigitux@git.wordpress.org> Co-authored-by: oandregal <oandregal@git.wordpress.org> Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
- Loading branch information
1 parent
609d573
commit 1ca8001
Showing
11 changed files
with
258 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { default as slugField } from './slug'; | ||
export { default as titleField } from './title'; | ||
export { default as orderField } from './order'; | ||
export { default as featuredImageField } from './featured-image'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import type { Field } from '@wordpress/dataviews'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { BasePost } from '../../types'; | ||
import { __ } from '@wordpress/i18n'; | ||
import SlugEdit from './slug-edit'; | ||
import SlugView from './slug-view'; | ||
|
||
const slugField: Field< BasePost > = { | ||
id: 'slug', | ||
type: 'text', | ||
label: __( 'Slug' ), | ||
getValue: ( { item } ) => item.slug, | ||
Edit: SlugEdit, | ||
render: SlugView, | ||
}; | ||
|
||
export default slugField; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
Button, | ||
ExternalLink, | ||
__experimentalInputControl as InputControl, | ||
__experimentalInputControlPrefixWrapper as InputControlPrefixWrapper, | ||
__experimentalVStack as VStack, | ||
} from '@wordpress/components'; | ||
import { copySmall } from '@wordpress/icons'; | ||
import { useCopyToClipboard, useInstanceId } from '@wordpress/compose'; | ||
import { useDispatch } from '@wordpress/data'; | ||
import { useCallback, useEffect, useRef } from '@wordpress/element'; | ||
import { store as noticesStore } from '@wordpress/notices'; | ||
import { safeDecodeURIComponent } from '@wordpress/url'; | ||
import type { DataFormControlProps } from '@wordpress/dataviews'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { BasePost } from '../../types'; | ||
|
||
const SlugEdit = ( { | ||
field, | ||
onChange, | ||
data, | ||
}: DataFormControlProps< BasePost > ) => { | ||
const { id } = field; | ||
|
||
const slug = field.getValue( { item: data } ) ?? ''; | ||
const permalinkTemplate = data.permalink_template || ''; | ||
const PERMALINK_POSTNAME_REGEX = /%(?:postname|pagename)%/; | ||
const [ prefix, suffix ] = permalinkTemplate.split( | ||
PERMALINK_POSTNAME_REGEX | ||
); | ||
const permalinkPrefix = prefix; | ||
const permalinkSuffix = suffix; | ||
const isEditable = PERMALINK_POSTNAME_REGEX.test( permalinkTemplate ); | ||
const originalSlug = useRef( slug ); | ||
const slugToDisplay = slug || originalSlug.current; | ||
const permalink = isEditable | ||
? `${ permalinkPrefix }${ slugToDisplay }${ permalinkSuffix }` | ||
: safeDecodeURIComponent( data.link || '' ); | ||
|
||
useEffect( () => { | ||
if ( slug && originalSlug.current === undefined ) { | ||
originalSlug.current = slug; | ||
} | ||
}, [ slug ] ); | ||
|
||
const onChangeControl = useCallback( | ||
( newValue?: string ) => | ||
onChange( { | ||
[ id ]: newValue, | ||
} ), | ||
[ id, onChange ] | ||
); | ||
|
||
const { createNotice } = useDispatch( noticesStore ); | ||
|
||
const copyButtonRef = useCopyToClipboard( permalink, () => { | ||
createNotice( 'info', __( 'Copied Permalink to clipboard.' ), { | ||
isDismissible: true, | ||
type: 'snackbar', | ||
} ); | ||
} ); | ||
|
||
const postUrlSlugDescriptionId = | ||
'editor-post-url__slug-description-' + useInstanceId( SlugEdit ); | ||
|
||
return ( | ||
<fieldset className="fields-controls__slug"> | ||
{ isEditable && ( | ||
<VStack> | ||
<VStack spacing="0px"> | ||
<span> | ||
{ __( | ||
'Customize the last part of the Permalink.' | ||
) } | ||
</span> | ||
<ExternalLink href="https://wordpress.org/documentation/article/page-post-settings-sidebar/#permalink"> | ||
{ __( 'Learn more' ) } | ||
</ExternalLink> | ||
</VStack> | ||
<InputControl | ||
__next40pxDefaultSize | ||
prefix={ | ||
<InputControlPrefixWrapper> | ||
/ | ||
</InputControlPrefixWrapper> | ||
} | ||
suffix={ | ||
<Button | ||
__next40pxDefaultSize | ||
icon={ copySmall } | ||
ref={ copyButtonRef } | ||
label={ __( 'Copy' ) } | ||
/> | ||
} | ||
label={ __( 'Link' ) } | ||
hideLabelFromVision | ||
value={ slug } | ||
autoComplete="off" | ||
spellCheck="false" | ||
type="text" | ||
className="fields-controls__slug-input" | ||
onChange={ ( newValue?: string ) => { | ||
onChangeControl( newValue ); | ||
} } | ||
onBlur={ () => { | ||
if ( slug === '' ) { | ||
onChangeControl( originalSlug.current ); | ||
} | ||
} } | ||
aria-describedby={ postUrlSlugDescriptionId } | ||
help={ | ||
<> | ||
<p className="fields-controls__slug-help"> | ||
<span className="fields-controls__slug-help-visual-label"> | ||
{ __( 'Permalink:' ) } | ||
</span> | ||
<ExternalLink | ||
className="fields-controls__slug-help-link" | ||
href={ permalink } | ||
> | ||
<span className="fields-controls__slug-help-prefix"> | ||
{ permalinkPrefix } | ||
</span> | ||
<span className="fields-controls__slug-help-slug"> | ||
{ slugToDisplay } | ||
</span> | ||
<span className="fields-controls__slug-help-suffix"> | ||
{ permalinkSuffix } | ||
</span> | ||
</ExternalLink> | ||
</p> | ||
</> | ||
} | ||
/> | ||
</VStack> | ||
) } | ||
{ ! isEditable && ( | ||
<ExternalLink | ||
className="fields-controls__slug-help" | ||
href={ permalink } | ||
> | ||
{ permalink } | ||
</ExternalLink> | ||
) } | ||
</fieldset> | ||
); | ||
}; | ||
|
||
export default SlugEdit; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useEffect, useRef } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { BasePost } from '../../types'; | ||
|
||
const SlugView = ( { item }: { item: BasePost } ) => { | ||
const slug = item.slug; | ||
const originalSlug = useRef( slug ); | ||
|
||
useEffect( () => { | ||
if ( slug && originalSlug.current === undefined ) { | ||
originalSlug.current = slug; | ||
} | ||
}, [ slug ] ); | ||
|
||
const slugToDisplay = slug || originalSlug.current; | ||
|
||
return `/${ slugToDisplay ?? '' }`; | ||
}; | ||
|
||
export default SlugView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.fields-controls__slug { | ||
.fields-controls__slug-external-icon { | ||
margin-left: 5ch; | ||
} | ||
|
||
.fields-controls__slug-input input.components-input-control__input { | ||
padding-inline-start: 0 !important; | ||
} | ||
|
||
.fields-controls__slug-help-link { | ||
word-break: break-word; | ||
} | ||
|
||
.fields-controls__slug-help { | ||
display: flex; | ||
flex-direction: column; | ||
|
||
.fields-controls__slug-help-slug { | ||
font-weight: 600; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@import "./fields/slug/style.scss"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters