/** * Embed dialog: one side menu of ways to place a player (preview, page, block, * shortcode, theme code, plus tabs registered by add-ons) * and a panel per option. Layout follows the "Embed dialog" boards of the builder * redesign canvas. */ import { __, sprintf } from '@wordpress/i18n'; import { Modal, Spinner } from '@wordpress/components'; import { useEffect, useMemo, useRef, useState } from '@wordpress/element'; import type { ReactNode } from 'react'; import { config, ss, openPreview, previewUrl, stations as stationsApi, } from './api'; import { I } from './ui'; import { getEmbedTabs, onExtensionsChange } from '../player/extensions'; type Id = string | number; /* ------------------------------------------------------------ primitives */ function copyText( text: string ): Promise< void > { if ( window.isSecureContext && navigator.clipboard?.writeText ) { return navigator.clipboard.writeText( text ); } return new Promise( ( resolve, reject ) => { const ta = document.createElement( 'textarea' ); ta.value = text; ta.setAttribute( 'readonly', '' ); ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild( ta ); ta.select(); try { document.execCommand( 'copy' ); resolve(); } catch ( e ) { reject( e ); } ta.remove(); } ); } /** Monospace snippet with a Copy button (works on http:// too). */ export function CodeBox( { code, large = false, wrap = false, compact = false, }: { code: string; large?: boolean; wrap?: boolean; compact?: boolean; } ) { const [ copied, setCopied ] = useState( false ); const copy = () => copyText( code ).then( () => { setCopied( true ); window.setTimeout( () => setCopied( false ), 1600 ); } ); return (
{ code }
); } function Seg< T extends string >( { value, options, onChange, label, }: { value: T; options: { value: T; label: string; icon?: string }[]; onChange: ( v: T ) => void; label: string; } ) { return ( { options.map( ( o ) => ( ) ) } ); } function Hint( { children }: { children: ReactNode } ) { return (
{ children }
); } function Field( { label, note, children, }: { label: string; note?: string; children: ReactNode; } ) { return (
{ label } { note ? { note } : null } { children }
); } function Toggle( { checked, onChange, label, }: { checked: boolean; onChange: ( v: boolean ) => void; label: string; } ) { return ( ); } /* ------------------------------------------------------------- Preview */ function PreviewPanel( { playerId }: { playerId: Id } ) { const [ theme, setTheme ] = useState< '' | 'light' | 'dark' >( '' ); const [ device, setDevice ] = useState< '' | 'tablet' | 'phone' >( '' ); const url = previewUrl( playerId, theme, device ); return ( <>