import { Button } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; import { useCallback, useEffect, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { STORE_NAME } from '../constants'; import { recordGuidelinesEvent } from '../lib/tracks'; import { AI_STORE_NAME } from '../store'; import DiffView from './diff-view'; export default function SuggestionActions( { slug } ) { const suggestion = useSelect( select => select( AI_STORE_NAME ).getSuggestion( slug ), [ slug ] ); const sectionLoading = useSelect( select => select( AI_STORE_NAME ).isSectionLoading( slug ), [ slug ] ); const { clearSuggestion } = useDispatch( AI_STORE_NAME ); const { setGuideline } = useDispatch( STORE_NAME ); const [ original, setOriginal ] = useState( '' ); const [ textareaHeight, setTextareaHeight ] = useState( null ); // Direct DOM class manipulation is necessary because this component is rendered in // a separate React root injected into Gutenberg's page — we can't control classes // on Gutenberg-owned elements through React props. useEffect( () => { const item = document.querySelector( `.guidelines__list-item[data-slug="${ slug }"]` ); const form = item?.querySelector( 'form' ); if ( ! form ) { return; } // Capture textarea draft and height before hiding it. if ( suggestion && ! form.classList.contains( 'has-jetpack-suggestion' ) ) { const textarea = form.querySelector( 'textarea' ); if ( textarea ) { setOriginal( textarea.value || '' ); if ( textarea.offsetHeight > 0 ) { setTextareaHeight( textarea.offsetHeight ); } else { // Fallback when textarea is hidden (e.g. collapsed accordion). // Compute height from rows attribute to match the textarea. const rows = parseInt( textarea.getAttribute( 'rows' ), 10 ) || 4; // line-height: 20px, padding: 9px top + 9px bottom, border: 1px + 1px. setTextareaHeight( rows * 20 + 20 ); } } } form.classList.toggle( 'has-jetpack-suggestion', !! suggestion ); form.classList.toggle( 'is-jetpack-loading', sectionLoading && ! suggestion ); return () => { form.classList.remove( 'has-jetpack-suggestion', 'is-jetpack-loading' ); }; }, [ slug, suggestion, sectionLoading ] ); const handleAccept = useCallback( () => { recordGuidelinesEvent( 'accept', { type: 'section', slug } ); setGuideline( slug, suggestion ); clearSuggestion( slug ); }, [ slug, suggestion, setGuideline, clearSuggestion ] ); const handleDismiss = useCallback( () => { recordGuidelinesEvent( 'dismiss', { type: 'section', slug } ); clearSuggestion( slug ); }, [ slug, clearSuggestion ] ); if ( ! suggestion ) { return null; } return (
); }