Skip to content

Commit

Permalink
Merge pull request #21821 from Yoast/323-fix-design-of-links-in-the-r…
Browse files Browse the repository at this point in the history
…elated-keyphrase-suggestions-modal-semrush

323 fix design of links in the related keyphrase suggestions modal semrush
  • Loading branch information
pls78 authored Nov 26, 2024
2 parents 78c95c4 + 7ff2b27 commit ce4d990
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 44 deletions.
41 changes: 20 additions & 21 deletions packages/js/src/components/SEMrushRelatedKeyphrasesModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import PropTypes from "prop-types";
import { NewButton, ButtonStyledLink } from "@yoast/components";

/* Internal dependencies */
import { ModalContainer } from "./modals/Container";
import Modal from "./modals/Modal";
import { ReactComponent as YoastIcon } from "../../images/Yoast_icon_kader.svg";
import { Modal } from "@yoast/related-keyphrase-suggestions";

/**
* Redux container for the RelatedKeyPhrasesModal modal.
Expand Down Expand Up @@ -154,7 +152,11 @@ class SEMrushRelatedKeyphrasesModal extends Component {
* @returns {wp.Element} The RelatedKeyPhrasesModal modal component.
*/
render() {
const { keyphrase, location, whichModalOpen, isLoggedIn, shouldCloseOnClickOutside, onClose } = this.props;
const { keyphrase, location, whichModalOpen, isLoggedIn, onClose, countryCode, learnMoreLink } = this.props;

const insightsLink = new URL( "https://www.semrush.com/analytics/keywordoverview/" );
insightsLink.searchParams.append( "q", keyphrase );
insightsLink.searchParams.append( "db", countryCode );

return (
<Fragment>
Expand All @@ -167,21 +169,16 @@ class SEMrushRelatedKeyphrasesModal extends Component {
{ __( "Get related keyphrases", "wordpress-seo" ) }
</NewButton>
</div> }
{ keyphrase && whichModalOpen === location &&
<Modal
title={ __( "Related keyphrases", "wordpress-seo" ) }
onRequestClose={ onClose }
icon={ <YoastIcon /> }
additionalClassName="yoast-related-keyphrases-modal"
shouldCloseOnClickOutside={ shouldCloseOnClickOutside }
>
<ModalContainer
className="yoast-gutenberg-modal__content yoast-related-keyphrases-modal__content"
>
<Slot name="YoastRelatedKeyphrases" />
</ModalContainer>
</Modal>
}
<Modal
isOpen={ Boolean( keyphrase ) && whichModalOpen === location }
onClose={ onClose }
insightsLink={ insightsLink.toString() }
learnMoreLink={ learnMoreLink }
>

<Slot name="YoastRelatedKeyphrases" />

</Modal>
{ ! isLoggedIn && <div className={ "yoast" }>
<ButtonStyledLink
variant={ "secondary" }
Expand Down Expand Up @@ -218,15 +215,17 @@ SEMrushRelatedKeyphrasesModal.propTypes = {
onOpenWithNoKeyphrase: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
onAuthentication: PropTypes.func.isRequired,
shouldCloseOnClickOutside: PropTypes.bool,
countryCode: PropTypes.string,
learnMoreLink: PropTypes.string,
};

SEMrushRelatedKeyphrasesModal.defaultProps = {
keyphrase: "",
location: "",
whichModalOpen: "none",
isLoggedIn: false,
shouldCloseOnClickOutside: true,
countryCode: "en_US",
learnMoreLink: "",
};

export default SEMrushRelatedKeyphrasesModal;
25 changes: 6 additions & 19 deletions packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
/* External dependencies */
import { KeyphrasesTable, UserMessage } from "@yoast/related-keyphrase-suggestions";
import { KeyphrasesTable, UserMessage, PremiumUpsell } from "@yoast/related-keyphrase-suggestions";
import { Root } from "@yoast/ui-library";
import { __, sprintf } from "@wordpress/i18n";
import PropTypes from "prop-types";
import { isEmpty } from "lodash";

/* Internal dependencies */
import SEMrushCountrySelector from "./modals/SEMrushCountrySelector";
import SEMrushUpsellAlert from "./modals/SEMrushUpsellAlert";
import { makeOutboundLink } from "@yoast/helpers";

/**
* Determines whether the error property is present in the passed response object.
Expand Down Expand Up @@ -93,14 +90,13 @@ export default function RelatedKeyphraseModalContent( props ) {
userLocale,
} = props;

const GetMoreInsightsLink = makeOutboundLink();
const url = "https://www.semrush.com/analytics/keywordoverview/?q=" + encodeURIComponent( keyphrase ) +
"&db=" + encodeURIComponent( countryCode );

return (
<Root context={ { isRtl } }>

{ ! requestLimitReached && ! isPremium && <SEMrushUpsellAlert /> }
{ ! requestLimitReached && ! isPremium && <PremiumUpsell
url={ window.wpseoAdminL10n[ "shortlinks.semrush.premium_landing_page" ] }
className="yst-mb-4"
/> }

{ ! requestLimitReached && <SEMrushCountrySelector
countryCode={ countryCode }
Expand All @@ -119,7 +115,6 @@ export default function RelatedKeyphraseModalContent( props ) {
{ ! isPending && <UserMessage
variant={ getUserMessage( props ) }
upsellLink={ window.wpseoAdminL10n[ "shortlinks.semrush.prices" ] }
className="yst-my-2"
/> }

<KeyphrasesTable
Expand All @@ -128,16 +123,8 @@ export default function RelatedKeyphraseModalContent( props ) {
data={ response?.results?.rows }
isPending={ isPending }
renderButton={ renderAction }
className="yst-mt-4"
/>
{ response?.results?.rows && <p className="yst-mb-0 yst-mt-2">
<GetMoreInsightsLink href={ url }>
{ sprintf(
/* translators: %s expands to Semrush */
__( "Get more insights at %s", "wordpress-seo" ),
"Semrush"
) }
</GetMoreInsightsLink>
</p> }
</Root>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const SEMrushCountrySelector = ( {
activeCountryCode={ activeCountryCode }
onChange={ setCountry }
onClick={ relatedKeyphrasesRequest }
className="yst-my-5 lg:yst-w-4/5"
className="yst-mb-4"
userLocale={ userLocale }
/>
);
Expand Down
9 changes: 7 additions & 2 deletions packages/js/src/containers/SEMrushRelatedKeyphrasesModal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { withDispatch, withSelect } from "@wordpress/data";
import { addQueryArgs } from "@wordpress/url";
import { compose } from "@wordpress/compose";
import SEMrushRelatedKeyphrasesModal from "../components/SEMrushRelatedKeyphrasesModal";

Expand All @@ -7,13 +8,17 @@ export default compose( [
const {
getSEMrushModalOpen,
getSEMrushLoginStatus,
getIsElementorEditor,
getSEMrushSelectedCountry,
getPreference,
selectLinkParams,
} = select( "yoast-seo/editor" );

return {
whichModalOpen: getSEMrushModalOpen(),
isLoggedIn: getSEMrushLoginStatus(),
shouldCloseOnClickOutside: ! getIsElementorEditor(),
countryCode: getSEMrushSelectedCountry(),
isRtl: getPreference( "isRtl", false ),
learnMoreLink: addQueryArgs( "https://yoa.st/3-v", selectLinkParams() ),
};
} ),
withDispatch( ( dispatch ) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@import "../src/elements/IntentBadge/style.css";
@import "../src/elements/DifficultyBullet/style.css";
@import "../src/elements/TableButton/style.css";
@import "../src/components/Modal/style.css";

@tailwind base;
@tailwind components;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export const CountrySelector = (
selectedLabel={ countryCode ? regionNames.of( countryCode.toUpperCase() ) : "" }
onChange={ onChange }
onQueryChange={ handleQueryChange }
className="yst-grow"
className="sm:yst-w-96"
>
{ filteredOptions.map( option => (
<AutocompleteField.Option key={ option.value } value={ option.value }>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The modal component with icon, title and links.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as component } from "./component.md";
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from "react";
import PropTypes from "prop-types";
import { __, sprintf } from "@wordpress/i18n";
import { Link, Modal as BaseModal } from "@yoast/ui-library";
import { ExternalLinkIcon, ArrowNarrowRightIcon } from "@heroicons/react/outline";
import { YoastIcon } from "./YoastIcon";

/**
* The modal component with header and footer links.
*
* @param {boolean} isOpen Whether the modal is open.
* @param {Function} onClose The function to call when the modal is closed.
* @param {string} insightsLink The links to the insights.
* @param {string} learnMoreLink The link to the learn more page.
* @param {JSX.node} children The content of the modal.
*
* @returns {JSX.Element} The modal component.
*/
export const Modal = ( { isOpen, onClose, insightsLink, learnMoreLink, children } ) => {
return (
<BaseModal
onClose={ onClose }
isOpen={ isOpen }
>
<BaseModal.Panel className="yst-p-0 yst-max-w-2xl">
<BaseModal.Container.Header className="yst-flex yst-gap-3 yst-p-6 yst-border-b-slate-200 yst-border-b yst-flex-row">
<YoastIcon />
<BaseModal.Title as="h3" className="yst-text-lg yst-font-medium">
{ __( "Related keyphrases", "wordpress-seo" ) }
</BaseModal.Title>
</BaseModal.Container.Header>
<BaseModal.Container.Content
className="yst-related-keyphrase-modal-content yst-m-0"
>
{ children }
</BaseModal.Container.Content>
<BaseModal.Container.Footer className="yst-p-6 yst-border-t yst-border-t-slate-200 yst-flex yst-justify-between">
<Link
href={ insightsLink }
className="yst-modal-footer-link"
target="_blank"
>
{ sprintf(
/* translators: %s expands to Semrush */
__( "Get more insights at %s", "wordpress-seo" ),
"Semrush",
) }
<span className="yst-sr-only">{ __( "(Opens in a new browser tab)", "wordpress-seo" ) }</span>
<ExternalLinkIcon className="yst-link-icon" />
</Link>
<Link
href={ learnMoreLink }
className="yst-modal-footer-link yst-text-primary-500"
target="_blank"
>
{ __( "Learn more about the metrics", "wordpress-seo" ) }
<span className="yst-sr-only">{ __( "(Opens in a new browser tab)", "wordpress-seo" ) }</span>
<ArrowNarrowRightIcon className="yst-link-icon" />
</Link>
</BaseModal.Container.Footer>
</BaseModal.Panel>
</BaseModal>
);
};

Modal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
insightsLink: PropTypes.string.isRequired,
learnMoreLink: PropTypes.string.isRequired,
children: PropTypes.node,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useEffect } from "react";
import { Button, useToggleState } from "@yoast/ui-library";
import { Modal } from ".";
import { component } from "./docs";
import { noop } from "lodash";

export const Factory = {
parameters: {
controls: { disable: false },
},
args: {
onClose: noop,
isOpen: false,
insightsLink: "https://insights.semrush.com/",
learnMoreLink: "https://learnmore.semrush.com/",
},
};

export default {
title: "1) Components/Modal",
component: Modal,
parameters: {
docs: {
description: { component },
},
},
render: ( { isOpen } ) => {
const [ open, toggleOpen, setOpen ] = useToggleState( isOpen );

useEffect( () => {
setOpen( isOpen );
}, [ isOpen ] );
return ( <>
<Button onClick={ toggleOpen }>
Open Modal
</Button>
<Modal isOpen={ open } onClose={ toggleOpen }> Hello World! </Modal></> );
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@layer components {
.yst-root {
.yst-modal-footer-link {
@apply yst-flex yst-flex-row yst-gap-1 yst-items-center;

.yst-link-icon {
@apply yst-w-3 yst-h-3;
}
}

.yst-related-keyphrase-modal-content {
max-height: 60vh;
min-height: 350px;
@apply yst-p-6 yst-overflow-y-auto;
}
}
}
1 change: 1 addition & 0 deletions packages/related-keyphrase-suggestions/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { TableButton } from "./elements/TableButton";
export { CountrySelector } from "./components/CountrySelector";
export { PremiumUpsell } from "./elements/PremiumUpsell";
export { UserMessage } from "./elements/UserMessage";
export { Modal } from "./components/Modal";

0 comments on commit ce4d990

Please sign in to comment.