import { getOption } from '@agent/lib/wp'; import { __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from '@wordpress/components'; import { useCallback, useEffect, useRef, useState } from '@wordpress/element'; import { __, _x } from '@wordpress/i18n'; import { flipVertical, Icon, notAllowed, shadow, square, } from '@wordpress/icons'; import classNames from 'classnames'; const animations = [ { // translators: Animation style where the element gradually appears by transitioning from transparent to visible. Translate as a simple, non-technical description of the visual effect (e.g., 'appear', 'show up') suitable for non-technical users. name: _x('Fade In', 'animation type', 'extendify-local'), slug: 'fade', icon: shadow, }, { // translators: Animation style where the element appears while moving upward. Translate as a simple, non-technical description of the motion (e.g., 'appear from below', 'rise into view') suitable for non-technical users. name: _x('Fade Up', 'animation type', 'extendify-local'), slug: 'fade-up', icon: flipVertical, }, { // translators: Animation style where the element appears by scaling from small to its full size. Translate as a simple, non-technical description of the effect (e.g., 'zoom in', 'get closer') suitable for non-technical users. If the target language commonly uses the English term 'zoom', it's acceptable to keep it. name: _x('Zoom In', 'animation type', 'extendify-local'), slug: 'zoom-in', icon: square, }, { // translators: None refers to 'no animation'. Apply the correct grammatical gender/form that agrees with the word for 'animation' in the target language. name: _x('None', 'animation type', 'extendify-local'), slug: 'none', icon: notAllowed, }, ]; const speeds = [ { // translators: "Slow" refers to a slower speed at which the animation effect occurs. This is an option in a list of animation speeds. name: _x('Slow', 'animation speed', 'extendify-local'), slug: 'slow', }, { // translators: "Medium" refers to a moderate speed at which the animation effect occurs. This is an option in a list of animation speeds. name: _x('Medium', 'animation speed', 'extendify-local'), slug: 'medium', }, { // translators: "Fast" refers to a quicker speed at which the animation effect occurs. This is an option in a list of animation speeds. name: _x('Fast', 'animation speed', 'extendify-local'), slug: 'fast', }, ]; export const SelectAnimation = ({ onConfirm, onCancel, onLoad }) => { const initialSettings = useRef({}); const [animation, setAnimation] = useState(null); const [touched, setTouched] = useState(0); const [speed, setSpeed] = useState(null); const [loading, setLoading] = useState(true); const undoAnimation = useCallback(() => { if (!touched) return; window.ExtendableAnimations?.setType(initialSettings.current.type); window.ExtendableAnimations?.setSpeed(initialSettings.current.speed); }, [touched]); const confirmed = useRef(false); // Ref keeps the latest undo function, so clean-up always sees the current `touched` state. const undoRef = useRef(undoAnimation); undoRef.current = undoAnimation; useEffect(() => { return () => { if (!confirmed.current) undoRef.current(); }; }, []); const handleConfirm = () => { if (!animation || !speed || loading) return; confirmed.current = true; onConfirm({ data: { type: animation, speed } }); }; useEffect(() => { if (!touched) return; window.ExtendableAnimations.setType(animation); window.ExtendableAnimations.setSpeed(speed); }, [speed, animation, touched]); useEffect(() => { if (loading) return; onLoad(); }, [loading, onLoad]); useEffect(() => { if (!loading) return; getOption('extendify_animation_settings').then((settings = {}) => { const defaults = { type: 'none', speed: 'medium' }; initialSettings.current = { ...defaults, ...(settings || {}) }; setAnimation(initialSettings.current.type); setSpeed(initialSettings.current.speed); setLoading(false); }); }, []); if (loading) { return (