Skip to content

Commit

Permalink
Creates a focus action in the store
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordi-PV committed Sep 18, 2024
1 parent 2088e28 commit ef31990
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PropTypes from "prop-types";
import { __ } from "@wordpress/i18n";
import { useCallback, useRef, useState } from "@wordpress/element";
import { useCallback, useRef, useState, useEffect } from "@wordpress/element";
import { doAction } from "@wordpress/hooks";
import { useSelect, useDispatch } from "@wordpress/data";

Expand All @@ -13,6 +13,7 @@ import { Paper } from "yoastseo";
import { ModalContent } from "./modal-content";
import { getAllBlocks } from "../../helpers/getAllBlocks";
import { LockClosedIcon } from "@heroicons/react/solid";
import { setFocusAIFixesButton } from "../../redux/actions";

/**
* The AI Assessment Fixes button component.
Expand All @@ -26,6 +27,7 @@ const AIAssessmentFixesButton = ( { id, isPremium } ) => {
const aiFixesId = id + "AIFixes";
const [ isModalOpen, , , setIsModalOpenTrue, setIsModalOpenFalse ] = useToggleState( false );
const activeAIButtonId = useSelect( select => select( "yoast-seo/editor" ).getActiveAIFixesButton(), [] );
const focusAIButton = useSelect( select => select( "yoast-seo/editor" ).getFocusAIFixesButton(), [] );
const activeMarker = useSelect( select => select( "yoast-seo/editor" ).getActiveMarker(), [] );
const { setActiveAIFixesButton, setActiveMarker, setMarkerPauseStatus, setMarkerStatus } = useDispatch( "yoast-seo/editor" );
const focusElementRef = useRef( null );
Expand All @@ -42,10 +44,11 @@ const AIAssessmentFixesButton = ( { id, isPremium } ) => {
// (2) the AI button is not disabled.
// (3) the editor is in visual mode.
// (4) all blocks are in visual mode.
const { isEnabled, ariaLabel, ariaHasPopup } = useSelect( ( select ) => {
const { isEnabled, isFocused, ariaLabel, ariaHasPopup } = useSelect( ( select ) => {
if ( activeAIButtonId !== null && ! isButtonPressed ) {
return {
isEnabled: false,
isFocused: false,
ariaLabel: null,
ariaHasPopup: false,
};
Expand All @@ -55,6 +58,7 @@ const AIAssessmentFixesButton = ( { id, isPremium } ) => {
if ( Object.keys( disabledAIButtons ).includes( aiFixesId ) ) {
return {
isEnabled: false,
isFocused: false,
ariaLabel: disabledAIButtons[ aiFixesId ],
ariaHasPopup: false,
};
Expand All @@ -64,6 +68,7 @@ const AIAssessmentFixesButton = ( { id, isPremium } ) => {
if ( editorMode !== "visual" ) {
return {
isEnabled: false,
isFocused: false,
ariaLabel: htmlLabel,
ariaHasPopup: false,
};
Expand All @@ -73,11 +78,23 @@ const AIAssessmentFixesButton = ( { id, isPremium } ) => {
const allVisual = blocks.every( block => select( "core/block-editor" ).getBlockMode( block.clientId ) === "visual" );
return {
isEnabled: allVisual,
isFocused: allVisual && focusAIButton === aiFixesId,
ariaLabel: allVisual ? defaultLabel : htmlLabel,
ariaHasPopup: allVisual ? "dialog" : false,
};
}, [ isButtonPressed, activeAIButtonId ] );

const buttonRef = useRef( null );

useEffect( () => {
if ( isFocused ) {
setTimeout( () => {
buttonRef.current?.focus();
}, 1000 );
setFocusAIFixesButton( false );
}
}, [ isFocused ] );

/**
* Handles the button press state.
* @returns {void}
Expand Down Expand Up @@ -147,6 +164,7 @@ const AIAssessmentFixesButton = ( { id, isPremium } ) => {
pressed={ isButtonPressed }
disabled={ ! isEnabled }
ariaHasPopup={ ariaHasPopup }
ref={ buttonRef }
>
{ ! isPremium && <LockClosedIcon className="yst-fixes-button__lock-icon yst-text-amber-900" /> }
<SparklesIcon pressed={ isButtonPressed } />
Expand Down
13 changes: 13 additions & 0 deletions packages/js/src/redux/actions/AIButton.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const SET_ACTIVE_AI_FIXES_BUTTON = "SET_ACTIVE_AI_FIXES_BUTTON";
export const SET_DISABLED_AI_FIXES_BUTTONS = "SET_DISABLED_AI_FIXES_BUTTONS";
export const SET_FOCUS_AI_FIXES_BUTTON = "SET_FOCUS_AI_FIXES_BUTTON";

/**
* Updates the active AI fixes button id.
Expand All @@ -24,3 +25,15 @@ export function setDisabledAIFixesButtons( disabledAIButtons ) {
disabledAIButtons,
};
}

/**
* Updates the focused AI button.
* @param {string} focusAIButton The focused AI buttons along with their reasons.
* @returns {Object} An action for redux.
*/
export function setFocusAIFixesButton( focusAIButton ) {
return {
type: SET_FOCUS_AI_FIXES_BUTTON,
focusAIButton,
};
}
14 changes: 12 additions & 2 deletions packages/js/src/redux/reducers/AIButton.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { SET_ACTIVE_AI_FIXES_BUTTON, SET_DISABLED_AI_FIXES_BUTTONS } from "../actions";
import { SET_ACTIVE_AI_FIXES_BUTTON, SET_DISABLED_AI_FIXES_BUTTONS, SET_FOCUS_AI_FIXES_BUTTON } from "../actions";

const INITIAL_STATE = {
activeAIButton: null,
focusAIButton: null,
disabledAIButtons: {},
};

Expand All @@ -15,10 +16,19 @@ const INITIAL_STATE = {
*/
export default function AIButton( state = INITIAL_STATE, action ) {
switch ( action.type ) {
case SET_ACTIVE_AI_FIXES_BUTTON:
case SET_ACTIVE_AI_FIXES_BUTTON: {
const focusAIButton = action.activeAIButton === null && state.activeAIButton !== null ? state.activeAIButton : state.focusAIButton;
console.log( "focusAIButton", focusAIButton );
return {
...state,
activeAIButton: action.activeAIButton,
focusAIButton,
};
}
case SET_FOCUS_AI_FIXES_BUTTON:
return {
...state,
focusAIButton: action.focusAIButton,
};
case SET_DISABLED_AI_FIXES_BUTTONS:
return {
Expand Down
8 changes: 8 additions & 0 deletions packages/js/src/redux/selectors/AIButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ export const getActiveAIFixesButton = state => get( state, "AIButton.activeAIBut
* @returns {object} The disabled buttons along with their reasons.
*/
export const getDisabledAIFixesButtons = state => get( state, "AIButton.disabledAIButtons", {} );


/**
* Returns the focus to the AI Fixes button.
* @param {object} state The state.
* @returns {string} Focus AI Fixes button id.
*/
export const getFocusAIFixesButton = state => get( state, "AIButton.focusAIButton", "" );

0 comments on commit ef31990

Please sign in to comment.