import { createInterpolateElement } from '@wordpress/element' import React, { useEffect, useRef, useState } from 'react' import { __, sprintf } from '@wordpress/i18n' import { useSnippetForm } from '../WithSnippetFormContext' import { DismissibleNotice } from '../../../common/Notice' import type { ReactNode } from 'react' const DESCRIPTION_INDEX = 2 const DETAILS_INDEX = 3 const hasStackTrace = (notice?: readonly unknown[]): boolean => Boolean(notice?.[DETAILS_INDEX]) const renderNoticeLine = (line: ReactNode): ReactNode => 'string' === typeof line ? createInterpolateElement(line, { strong: }) : line interface NoticesProps { placement: 'above-form' | 'sidebar' } const StackTraceDetails: React.FC<{ trace: string }> = ({ trace }) => { const preRef = useRef(null) const [isOpen, setIsOpen] = useState(false) const [showHint, setShowHint] = useState(false) useEffect(() => { if (!isOpen) { setShowHint(false) return } const updateHintVisibility = () => { const pre = preRef.current setShowHint(Boolean(pre && pre.scrollWidth > pre.clientWidth)) } updateHintVisibility() window.addEventListener('resize', updateHintVisibility) return () => { window.removeEventListener('resize', updateHintVisibility) } }, [isOpen, trace]) return (
setIsOpen(event.currentTarget.open)}> {__('View stack trace', 'code-snippets')}
{trace}
{showHint ?

{__('Scroll horizontally if the trace is cut off.', 'code-snippets')}

: null}
) } export const Notices: React.FC = ({ placement }) => { const { currentNotice, setCurrentNotice, snippet, setSnippet } = useSnippetForm() const showCurrentNotice = 'above-form' === placement ? hasStackTrace(currentNotice) : !hasStackTrace(currentNotice) const showCodeErrorNotice = 'sidebar' === placement && !snippet.code_error_trace return <> {showCurrentNotice && currentNotice ? setCurrentNotice(undefined)} >

{renderNoticeLine(currentNotice[1])}

{currentNotice[DESCRIPTION_INDEX] ?

{renderNoticeLine(currentNotice[DESCRIPTION_INDEX])}

: null} {currentNotice[DETAILS_INDEX] ? : null}
: null} {showCodeErrorNotice && !currentNotice && snippet.code_error ? setSnippet(previous => ({ ...previous, code_error: null, code_error_trace: null }))} >

{sprintf( // translators: %d: line number. __('Snippet automatically deactivated due to an error on line %d:', 'code-snippets'), snippet.code_error[1] )}

{snippet.code_error[0]}

: null} }