diff --git a/packages/js/src/components/SEMrushRelatedKeyphrasesModal.js b/packages/js/src/components/SEMrushRelatedKeyphrasesModal.js index 1914d873a19..160b8c4bcdc 100644 --- a/packages/js/src/components/SEMrushRelatedKeyphrasesModal.js +++ b/packages/js/src/components/SEMrushRelatedKeyphrasesModal.js @@ -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. @@ -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 ( @@ -167,21 +169,16 @@ class SEMrushRelatedKeyphrasesModal extends Component { { __( "Get related keyphrases", "wordpress-seo" ) } } - { keyphrase && whichModalOpen === location && - } - additionalClassName="yoast-related-keyphrases-modal" - shouldCloseOnClickOutside={ shouldCloseOnClickOutside } - > - - - - - } + + + + + { ! isLoggedIn &&
} { ! requestLimitReached && } - { response?.results?.rows &&

- - { sprintf( - /* translators: %s expands to Semrush */ - __( "Get more insights at %s", "wordpress-seo" ), - "Semrush" - ) } - -

} ); } diff --git a/packages/js/src/components/modals/SEMrushCountrySelector.js b/packages/js/src/components/modals/SEMrushCountrySelector.js index 24fabfec842..52c9aa2f51d 100644 --- a/packages/js/src/components/modals/SEMrushCountrySelector.js +++ b/packages/js/src/components/modals/SEMrushCountrySelector.js @@ -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 } /> ); diff --git a/packages/js/src/containers/SEMrushRelatedKeyphrasesModal.js b/packages/js/src/containers/SEMrushRelatedKeyphrasesModal.js index 6238663335a..53ef5861da7 100644 --- a/packages/js/src/containers/SEMrushRelatedKeyphrasesModal.js +++ b/packages/js/src/containers/SEMrushRelatedKeyphrasesModal.js @@ -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"; @@ -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 ) => { diff --git a/packages/related-keyphrase-suggestions/.storybook/style.css b/packages/related-keyphrase-suggestions/.storybook/style.css index 8aaa132997c..d79d22b4925 100644 --- a/packages/related-keyphrase-suggestions/.storybook/style.css +++ b/packages/related-keyphrase-suggestions/.storybook/style.css @@ -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; diff --git a/packages/related-keyphrase-suggestions/src/components/CountrySelector/index.js b/packages/related-keyphrase-suggestions/src/components/CountrySelector/index.js index 0f84352860a..9be6b521868 100644 --- a/packages/related-keyphrase-suggestions/src/components/CountrySelector/index.js +++ b/packages/related-keyphrase-suggestions/src/components/CountrySelector/index.js @@ -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 => ( diff --git a/packages/related-keyphrase-suggestions/src/components/Modal/YoastIcon.js b/packages/related-keyphrase-suggestions/src/components/Modal/YoastIcon.js new file mode 100644 index 00000000000..83ebae44290 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/components/Modal/YoastIcon.js @@ -0,0 +1,13 @@ +import React from "react"; + +/** + * The Yoast icon component. + * + * @returns {JSX.Element} The Yoast icon component. + */ +export const YoastIcon = () => { + return ( + ); +}; diff --git a/packages/related-keyphrase-suggestions/src/components/Modal/docs/component.md b/packages/related-keyphrase-suggestions/src/components/Modal/docs/component.md new file mode 100644 index 00000000000..04e485ecd15 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/components/Modal/docs/component.md @@ -0,0 +1 @@ +The modal component with icon, title and links. \ No newline at end of file diff --git a/packages/related-keyphrase-suggestions/src/components/Modal/docs/index.js b/packages/related-keyphrase-suggestions/src/components/Modal/docs/index.js new file mode 100644 index 00000000000..a01392a1542 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/components/Modal/docs/index.js @@ -0,0 +1 @@ +export { default as component } from "./component.md"; diff --git a/packages/related-keyphrase-suggestions/src/components/Modal/index.js b/packages/related-keyphrase-suggestions/src/components/Modal/index.js new file mode 100644 index 00000000000..9e9bfd35451 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/components/Modal/index.js @@ -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 ( + + + + + + { __( "Related keyphrases", "wordpress-seo" ) } + + + + { children } + + + + { sprintf( + /* translators: %s expands to Semrush */ + __( "Get more insights at %s", "wordpress-seo" ), + "Semrush", + ) } + { __( "(Opens in a new browser tab)", "wordpress-seo" ) } + + + + { __( "Learn more about the metrics", "wordpress-seo" ) } + { __( "(Opens in a new browser tab)", "wordpress-seo" ) } + + + + + + ); +}; + +Modal.propTypes = { + isOpen: PropTypes.bool.isRequired, + onClose: PropTypes.func.isRequired, + insightsLink: PropTypes.string.isRequired, + learnMoreLink: PropTypes.string.isRequired, + children: PropTypes.node, +}; diff --git a/packages/related-keyphrase-suggestions/src/components/Modal/stories.js b/packages/related-keyphrase-suggestions/src/components/Modal/stories.js new file mode 100644 index 00000000000..301c7bb3a52 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/components/Modal/stories.js @@ -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 ( <> + + Hello World! ); + }, +}; diff --git a/packages/related-keyphrase-suggestions/src/components/Modal/style.css b/packages/related-keyphrase-suggestions/src/components/Modal/style.css new file mode 100644 index 00000000000..496b7a822e1 --- /dev/null +++ b/packages/related-keyphrase-suggestions/src/components/Modal/style.css @@ -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; + } + } +} \ No newline at end of file diff --git a/packages/related-keyphrase-suggestions/src/index.js b/packages/related-keyphrase-suggestions/src/index.js index a7523d49117..82aa20d677a 100644 --- a/packages/related-keyphrase-suggestions/src/index.js +++ b/packages/related-keyphrase-suggestions/src/index.js @@ -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";