From 35e9827d550d42141e29dfa72a401eb55f78e0e5 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Sat, 18 Jan 2025 00:23:55 +0200 Subject: [PATCH 01/85] stepper for ui-library add stepper to ui library export stepper fix stories args move margin out of the plugin fix story space --- packages/ui-library/.storybook/style.css | 1 + .../src/elements/stepper/docs/component.md | 1 + .../src/elements/stepper/docs/index.js | 1 + .../ui-library/src/elements/stepper/index.js | 126 ++++++++++++++++++ .../src/elements/stepper/stories.js | 68 ++++++++++ .../ui-library/src/elements/stepper/style.css | 32 +++++ packages/ui-library/src/index.js | 1 + 7 files changed, 230 insertions(+) create mode 100644 packages/ui-library/src/elements/stepper/docs/component.md create mode 100644 packages/ui-library/src/elements/stepper/docs/index.js create mode 100644 packages/ui-library/src/elements/stepper/index.js create mode 100644 packages/ui-library/src/elements/stepper/stories.js create mode 100644 packages/ui-library/src/elements/stepper/style.css diff --git a/packages/ui-library/.storybook/style.css b/packages/ui-library/.storybook/style.css index 498e30b3a16..fa96907fa11 100644 --- a/packages/ui-library/.storybook/style.css +++ b/packages/ui-library/.storybook/style.css @@ -21,6 +21,7 @@ @import "../src/elements/file-input/style.css"; @import "../src/elements/autocomplete/style.css"; @import "../src/elements/validation/style.css"; +@import "../src/elements/stepper/style.css"; @import "../src/components/autocomplete-field/style.css"; @import "../src/components/card/style.css"; diff --git a/packages/ui-library/src/elements/stepper/docs/component.md b/packages/ui-library/src/elements/stepper/docs/component.md new file mode 100644 index 00000000000..2f30c0b3a2c --- /dev/null +++ b/packages/ui-library/src/elements/stepper/docs/component.md @@ -0,0 +1 @@ +The stepper element takes a list of steps labels, the current step and is the process complete. \ No newline at end of file diff --git a/packages/ui-library/src/elements/stepper/docs/index.js b/packages/ui-library/src/elements/stepper/docs/index.js new file mode 100644 index 00000000000..a01392a1542 --- /dev/null +++ b/packages/ui-library/src/elements/stepper/docs/index.js @@ -0,0 +1 @@ +export { default as component } from "./component.md"; diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js new file mode 100644 index 00000000000..20cebc0b8ae --- /dev/null +++ b/packages/ui-library/src/elements/stepper/index.js @@ -0,0 +1,126 @@ +import classNames from "classnames"; +import PropTypes from "prop-types"; +import React, { forwardRef, useRef, useEffect, useState, useCallback } from "react"; +import { CheckIcon } from "@heroicons/react/solid"; + +/** + * Step component. + * + * @param {string} label The step label. + * @param {number} index The step index. + * @param {boolean} isComplete Is the step complete. + * @param {number} currentStep The current step. + * @param {function} addStepRef The function to add the step ref. + * + * @returns {JSX.Element} The step element. + */ +const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => { + const handleRef = useCallback( ( el ) =>{ + addStepRef( el, index ); + }, [] ); + return ( +
index + 1 || isComplete ? "yst-step--complete" : "", + currentStep === index + 1 ? "yst-step--active" : "" ) } + > +
+ { ( currentStep > index + 1 || isComplete ) && } + + { ! isComplete && currentStep === index + 1 && + + } +
+
{ label }
+
+ ); +}; + +Step.propTypes = { + label: PropTypes.string.isRequired, + index: PropTypes.number.isRequired, + isComplete: PropTypes.bool.isRequired, + currentStep: PropTypes.number.isRequired, + addStepRef: PropTypes.func.isRequired, +}; + +/** + * + * @param {number} currentStep The currrent step. + * @param {boolean} isComplete Is the step complete. + * @param {array} steps The steps names. + * @param {string} [className] Optional extra className. + * @returns {JSX.Element} The Stepper element. + */ +const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" }, ref ) => { + const [ margins, setMargins ] = useState( { + marginLeft: 0, + marginRight: 0, + } ); + const stepRef = useRef( [] ); + + useEffect( () => { + setMargins( { + marginLeft: stepRef.current[ 0 ].offsetWidth / 2, + marginRight: stepRef.current[ steps.length - 1 ].offsetWidth / 2, + } ); + }, [ stepRef, steps.length ] ); + + if ( ! steps.length ) { + return <>; + } + + const calculateProgressBarWidth = () => { + return ( ( currentStep - 1 ) / ( steps.length - 1 ) ) * 100; + }; + + const addStepRef = useCallback( ( el, index ) => ( stepRef.current[ index ] = el ), [ stepRef ] ); + + return ( +
+ { steps.map( ( step, index ) => ) } + + { /* Progress bar */ } +
+ + { /* Progress */ } +
+
+
+ + ); +} ); + +Stepper.displayName = "Stepper"; +Stepper.propTypes = { + currentStep: PropTypes.number.isRequired, + isComplete: PropTypes.bool.isRequired, + steps: PropTypes.arrayOf( PropTypes.shape( { + label: PropTypes.string, + } ) ).isRequired, + className: PropTypes.string, +}; +Stepper.defaultProps = { + className: "", +}; + +export default Stepper; diff --git a/packages/ui-library/src/elements/stepper/stories.js b/packages/ui-library/src/elements/stepper/stories.js new file mode 100644 index 00000000000..bcb0f7e1afb --- /dev/null +++ b/packages/ui-library/src/elements/stepper/stories.js @@ -0,0 +1,68 @@ +import React, { useState, useCallback } from "react"; +import Stepper from "."; +import { component } from "./docs"; +import Button from "../button/index"; + +export const Factory = { + parameters: { + controls: { disable: false }, + }, + render: ( args ) =>{ + const [ currentStep, setCurrentStep ] = useState( 1 ); + const [ isComplete, setIsComplete ] = useState( false ); + + const handleNext = useCallback( () => { + setCurrentStep( ( prevStep ) => { + if ( isComplete ) { + setIsComplete( false ); + return 1; + } + if ( prevStep === args.steps.length ) { + setIsComplete( true ); + return prevStep; + } + return prevStep + 1; + } ); + }, [ setIsComplete, setCurrentStep, isComplete ] ); + + return <> + + + + ; + }, +}; + +export default { + title: "1) Elements/Stepper", + component: Stepper, + argTypes: { + steps: { control: false }, + }, + parameters: { + docs: { + description: { component }, + }, + }, + args: { + steps: [ + { + label: "INSTALL", + }, + { + label: "ACTIVATE", + }, + { + label: "SET UP", + }, + { + label: "CONNECT", + }, + ], + className: "yst-mb-5", + }, +}; diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/elements/stepper/style.css new file mode 100644 index 00000000000..6717175d659 --- /dev/null +++ b/packages/ui-library/src/elements/stepper/style.css @@ -0,0 +1,32 @@ +@layer components { + .yst-root { + + .yst-stepper { + @apply yst-relative yst-flex yst-justify-between yst-items-center; + } + + .yst-step-circle { + @apply yst-bg-white + yst-border-slate-300 + yst-w-6 + yst-h-6 + yst-border-2 + yst-rounded-full + yst-flex + yst-items-center + yst-justify-center + yst-z-10; + } + + .yst-step--active .yst-step-circle { + @apply yst-bg-white yst-text-white yst-border-primary-500; + } + + .yst-step--complete { + .yst-step-circle { + @apply yst-bg-primary-500 yst-text-white yst-border-primary-500; + } + } + + } +} diff --git a/packages/ui-library/src/index.js b/packages/ui-library/src/index.js index 830ac850945..4c9b7f978fc 100644 --- a/packages/ui-library/src/index.js +++ b/packages/ui-library/src/index.js @@ -22,6 +22,7 @@ export { default as Toast, useToastContext } from "./elements/toast"; export { default as Toggle } from "./elements/toggle"; export { default as Tooltip } from "./elements/tooltip"; export { ValidationIcon, ValidationInput, ValidationMessage } from "./elements/validation"; +export { default as Stepper } from "./elements/stepper"; export { default as AutocompleteField } from "./components/autocomplete-field"; export { default as Card } from "./components/card"; From 32e99389a8ea7382baab1d9814306744f3fb88dc Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Sat, 18 Jan 2025 01:00:47 +0200 Subject: [PATCH 02/85] implement the stepper and design add translation to the stepper --- .../images/yoast-connect-google-site-kit.svg | 69 +++++++++++++++++++ .../google-site-kit-connection-widget.js | 42 +++++++++++ 2 files changed, 111 insertions(+) create mode 100644 packages/js/images/yoast-connect-google-site-kit.svg create mode 100644 packages/js/src/dashboard/components/google-site-kit-connection-widget.js diff --git a/packages/js/images/yoast-connect-google-site-kit.svg b/packages/js/images/yoast-connect-google-site-kit.svg new file mode 100644 index 00000000000..9cc11d73f58 --- /dev/null +++ b/packages/js/images/yoast-connect-google-site-kit.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js new file mode 100644 index 00000000000..513ef8e7998 --- /dev/null +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -0,0 +1,42 @@ +import { Button, Paper, Stepper, Title } from "@yoast/ui-library"; +import { ReactComponent as YoastConnectSiteKit } from "../../../images/yoast-connect-google-site-kit.svg"; +import { __ } from "@wordpress/i18n"; +import { CheckCircleIcon } from "@heroicons/react/solid"; +import { ArrowRightIcon } from "@heroicons/react/outline"; + + +/** + * The google site kit connection guide widget. + * + * @returns {JSX.Element} The widget. + */ +export const GoogleSiteKitConnectionWidget = () => { + const steps = [ + { label: __( "INSTALL", "wordpress-seo" ) }, + { label: __( "ACTIVATE", "wordpress-seo" ) }, + { label: __( "SET UP", "wordpress-seo" ) }, + { label: __( "CONNECT", "wordpress-seo" ) }, + ]; + + return +
+ +
+ { __( "Expand your dashboard with insights from Google!", "wordpress-seo" ) } +

{ __( "Bring together powerful tools like Google Analytics and Search Console for a complete overview of your website's performance, all in one seamless dashboard.", "wordpress-seo" ) }

+ + { __( "What you'll get:", "wordpress-seo" ) } +
    +
  • + { __( "Actionable insights into traffic, SEO, and user behavior to grow your audience.", "wordpress-seo" ) }
  • +
  • + { __( "Key performance metrics to fine-tune your website and optimize like a pro.", "wordpress-seo" ) }
  • +
+
+ + +
+
; +}; From c8daeaa731b2bfc63f33a420e12e05b29eacdaf9 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 12:10:53 +0200 Subject: [PATCH 03/85] implement stepper and gsk status --- .../js/src/dashboard/components/dashboard.js | 14 ++++ .../google-site-kit-connection-widget.js | 73 +++++++++++++++++-- .../configuration/dashboard-configuration.php | 53 +++++++++++++- 3 files changed, 132 insertions(+), 8 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 62f58e02edc..ad11f2a8929 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -1,5 +1,7 @@ import { Scores } from "../scores/components/scores"; import { PageTitle } from "./page-title"; +import { GoogleSiteKitConnectionWidget } from "./google-site-kit-connection-widget"; +import { get } from "lodash"; /** * @type {import("../index").ContentType} ContentType @@ -18,10 +20,22 @@ import { PageTitle } from "./page-title"; * @returns {JSX.Element} The element. */ export const Dashboard = ( { contentTypes, userName, features, endpoints, headers, links } ) => { + const googleSiteKitConfiguration = get( window, "wpseoScriptData.dashboard.google_site_kit", { + installed: false, + featureActive: false, + active: false, + setup: false, + connected: false, + installUrl: "", + activateUrl: "", + setupUrl: "", + } ); + return ( <>
+ { googleSiteKitConfiguration.featureActive && } { features.indexables && features.seoAnalysis && ( ) } diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 513ef8e7998..ffd2d7f71c8 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -8,9 +8,25 @@ import { ArrowRightIcon } from "@heroicons/react/outline"; /** * The google site kit connection guide widget. * + * @param {boolean} setup Whether the setup is complete. + * @param {boolean} active Whether the feature is active. + * @param {boolean} connected Whether the connection is active. + * @param {boolean} installed Whether the plugin is installed. + * @param {boolean} featureActive Whether the feature is active. + * @param {string} activateUrl The URL to activate Site Kit. + * @param {string} installUrl The URL to install Site Kit. + * * @returns {JSX.Element} The widget. */ -export const GoogleSiteKitConnectionWidget = () => { +export const GoogleSiteKitConnectionWidget = ( { + installUrl, + activateUrl, + setupUrl, + connected, + active, + setup, + installed, +} ) => { const steps = [ { label: __( "INSTALL", "wordpress-seo" ) }, { label: __( "ACTIVATE", "wordpress-seo" ) }, @@ -18,9 +34,51 @@ export const GoogleSiteKitConnectionWidget = () => { { label: __( "CONNECT", "wordpress-seo" ) }, ]; + const learnMorelink = "https://yoa.st/dashboard-google-site-kit-learn-more"; + let buttonProps; + let currentStep; + let isComplete; + + switch ( true ) { + case ( ! installed ): + currentStep = 1; + buttonProps = { + children: __( "Install Site Kit by Google", "wordpress-seo" ), + as: "a", + href: installUrl, + }; + break; + case ( ! active ): + currentStep = 2; + buttonProps = { + children: __( "Activate Site Kit by Google", "wordpress-seo" ), + as: "a", + href: activateUrl, + }; + break; + case ( ! setup ): + currentStep = 3; + buttonProps = { + children: __( "Set up Site Kit by Google", "wordpress-seo" ), + as: "a", + href: setupUrl, + }; + break; + case ( ! connected ): + currentStep = 4; + buttonProps = { children: __( "Connect Site Kit by Google", "wordpress-seo" ) }; + break; + case connected: + isComplete = true; + currentStep = 4; + buttonProps = { children: "Take a quick tour" }; + break; + } + + console.log( buttonProps, currentStep, isComplete ); return
- +
{ __( "Expand your dashboard with insights from Google!", "wordpress-seo" ) }

{ __( "Bring together powerful tools like Google Analytics and Search Console for a complete overview of your website's performance, all in one seamless dashboard.", "wordpress-seo" ) }

@@ -33,10 +91,13 @@ export const GoogleSiteKitConnectionWidget = () => { { __( "Key performance metrics to fine-tune your website and optimize like a pro.", "wordpress-seo" ) }
- - + + : + }
; }; diff --git a/src/dashboard/application/configuration/dashboard-configuration.php b/src/dashboard/application/configuration/dashboard-configuration.php index eae738da4a0..779933a54cb 100644 --- a/src/dashboard/application/configuration/dashboard-configuration.php +++ b/src/dashboard/application/configuration/dashboard-configuration.php @@ -4,6 +4,7 @@ // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong namespace Yoast\WP\SEO\Dashboard\Application\Configuration; +use Yoast\WP\SEO\Conditionals\Google_Site_Kit_Feature_Conditional; use Yoast\WP\SEO\Dashboard\Application\Content_Types\Content_Types_Repository; use Yoast\WP\SEO\Dashboard\Application\Endpoints\Endpoints_Repository; use Yoast\WP\SEO\Dashboard\Infrastructure\Nonces\Nonce_Repository; @@ -11,6 +12,7 @@ use Yoast\WP\SEO\Editors\Framework\Keyphrase_Analysis; use Yoast\WP\SEO\Editors\Framework\Readability_Analysis; use Yoast\WP\SEO\Helpers\Indexable_Helper; +use Yoast\WP\SEO\Helpers\Options_Helper; use Yoast\WP\SEO\Helpers\User_Helper; /** @@ -60,6 +62,20 @@ class Dashboard_Configuration { */ private $nonce_repository; + /** + * The Google Site Kit conditional. + * + * @var Google_Site_Kit_Feature_Conditional + */ + private $google_site_kit_conditional; + + /** + * The options helper. + * + * @var Options_Helper + */ + private $options_helper; + /** * The constructor. * @@ -68,7 +84,9 @@ class Dashboard_Configuration { * repository. * @param User_Helper $user_helper The user helper. * @param Enabled_Analysis_Features_Repository $enabled_analysis_features_repository The analysis feature - * repository. + * @param Options_Helper $options_helper The options helper. + * @param Google_Site_Kit_Feature_Conditional $google_site_kit_conditional The Google Site Kit conditional. + * repository. * @param Endpoints_Repository $endpoints_repository The endpoints repository. * @param Nonce_Repository $nonce_repository The nonce repository. */ @@ -78,7 +96,9 @@ public function __construct( User_Helper $user_helper, Enabled_Analysis_Features_Repository $enabled_analysis_features_repository, Endpoints_Repository $endpoints_repository, - Nonce_Repository $nonce_repository + Nonce_Repository $nonce_repository, + Google_Site_Kit_Feature_Conditional $google_site_kit_conditional, + Options_Helper $options_helper ) { $this->content_types_repository = $content_types_repository; $this->indexable_helper = $indexable_helper; @@ -86,6 +106,8 @@ public function __construct( $this->enabled_analysis_features_repository = $enabled_analysis_features_repository; $this->endpoints_repository = $endpoints_repository; $this->nonce_repository = $nonce_repository; + $this->google_site_kit_conditional = $google_site_kit_conditional; + $this->options_helper = $options_helper; } /** @@ -106,6 +128,33 @@ public function get_configuration(): array { )->to_array(), 'endpoints' => $this->endpoints_repository->get_all_endpoints()->to_array(), 'nonce' => $this->nonce_repository->get_rest_nonce(), + 'google_site_kit' => $this->get_google_site_kit_configuration(), + ]; + } + + public function get_google_site_kit_configuration(): array { + $google_site_kit_file = 'google-site-kit/google-site-kit.php'; + $google_site_kit_activate_url = \wp_nonce_url( + \self_admin_url( 'plugins.php?action=activate&plugin=' . $google_site_kit_file ), + 'activate-plugin_' . $google_site_kit_file + ); + + $google_site_kit_install_url = \wp_nonce_url( + \self_admin_url( 'update.php?action=install-plugin&plugin=google-site-kit' ), + 'install-plugin_google-site-kit' + ); + + $google_site_kit_setup_url = \self_admin_url( 'admin.php?page=googlesitekit-splash' ); + + return [ + 'installed' => \file_exists( \WP_PLUGIN_DIR . '/' . $google_site_kit_file ), + 'active' => \is_plugin_active( $google_site_kit_file ), + 'setup' => \get_option( 'googlesitekit_has_connected_admins', false ) === '1', + 'connected' => $this->options_helper->get( 'google_site_kit_connected', false ), + 'featureActive' => $this->google_site_kit_conditional->is_met(), + 'installUrl' => $google_site_kit_install_url, + 'activateUrl' => $google_site_kit_activate_url, + 'setupUrl' => $google_site_kit_setup_url, ]; } } From bce65d992a6103b6ef0fd8e4158c4c0e4cfed1e4 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 12:45:05 +0200 Subject: [PATCH 04/85] reduce complexity and add link params --- .../google-site-kit-connection-widget.js | 92 +++++++++++-------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index ffd2d7f71c8..c30a71ad507 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -3,52 +3,33 @@ import { ReactComponent as YoastConnectSiteKit } from "../../../images/yoast-con import { __ } from "@wordpress/i18n"; import { CheckCircleIcon } from "@heroicons/react/solid"; import { ArrowRightIcon } from "@heroicons/react/outline"; - +import { useSelect } from "@wordpress/data"; +import { addQueryArgs } from "@wordpress/url"; /** - * The google site kit connection guide widget. + * Get the button and stepper props based on the current state. * - * @param {boolean} setup Whether the setup is complete. * @param {boolean} active Whether the feature is active. - * @param {boolean} connected Whether the connection is active. * @param {boolean} installed Whether the plugin is installed. - * @param {boolean} featureActive Whether the feature is active. - * @param {string} activateUrl The URL to activate Site Kit. + * @param {boolean} setup Whether the setup is complete. + * @param {boolean} connected Whether the connection is active. * @param {string} installUrl The URL to install Site Kit. + * @param {string} activateUrl The URL to activate Site Kit. + * @param {string} setupUrl The URL to setup Site Kit. * - * @returns {JSX.Element} The widget. + * @returns {Object} The button and stepper props. */ -export const GoogleSiteKitConnectionWidget = ( { - installUrl, - activateUrl, - setupUrl, - connected, - active, - setup, - installed, -} ) => { - const steps = [ - { label: __( "INSTALL", "wordpress-seo" ) }, - { label: __( "ACTIVATE", "wordpress-seo" ) }, - { label: __( "SET UP", "wordpress-seo" ) }, - { label: __( "CONNECT", "wordpress-seo" ) }, - ]; - - const learnMorelink = "https://yoa.st/dashboard-google-site-kit-learn-more"; - let buttonProps; - let currentStep; - let isComplete; +const getButtonAndStepperProps = ( active, installed, setup, connected, installUrl, activateUrl, setupUrl ) => { + let buttonProps = { + children: __( "Install Site Kit by Google", "wordpress-seo" ), + as: "a", + href: installUrl, + }; + let currentStep = 1; + let isComplete = false; switch ( true ) { - case ( ! installed ): - currentStep = 1; - buttonProps = { - children: __( "Install Site Kit by Google", "wordpress-seo" ), - as: "a", - href: installUrl, - }; - break; - case ( ! active ): + case ( ! active && installed ): currentStep = 2; buttonProps = { children: __( "Activate Site Kit by Google", "wordpress-seo" ), @@ -74,8 +55,43 @@ export const GoogleSiteKitConnectionWidget = ( { buttonProps = { children: "Take a quick tour" }; break; } + return { buttonProps, currentStep, isComplete }; +}; + +/** + * The google site kit connection guide widget. + * + * @param {boolean} installed Whether the plugin is installed. + * @param {boolean} setup Whether the setup is complete. + * @param {boolean} active Whether the feature is active. + * @param {boolean} connected Whether the connection is active. + * @param {boolean} installed Whether the plugin is installed. + * @param {string} activateUrl The URL to activate Site Kit. + * @param {string} installUrl The URL to install Site Kit. + * + * @returns {JSX.Element} The widget. + */ +export const GoogleSiteKitConnectionWidget = ( { + installUrl, + activateUrl, + setupUrl, + connected, + active, + setup, + installed, +} ) => { + const steps = [ + { label: __( "INSTALL", "wordpress-seo" ) }, + { label: __( "ACTIVATE", "wordpress-seo" ) }, + { label: __( "SET UP", "wordpress-seo" ) }, + { label: __( "CONNECT", "wordpress-seo" ) }, + ]; - console.log( buttonProps, currentStep, isComplete ); + const linkParams = useSelect( select => select( "@yoast/general" ).selectLinkParams(), [] ); + const learnMorelink = addQueryArgs( "https://yoa.st/google-site-kit-learn-more", linkParams ); + + const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( + active, installed, setup, connected, installUrl, activateUrl, setupUrl ); return
@@ -101,3 +117,5 @@ export const GoogleSiteKitConnectionWidget = ( {
; }; + + From 0af104aa62c1e50498ffc1c5e5a6d71a85448551 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 13:09:38 +0200 Subject: [PATCH 05/85] fix php cs --- .../configuration/dashboard-configuration.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dashboard/application/configuration/dashboard-configuration.php b/src/dashboard/application/configuration/dashboard-configuration.php index 779933a54cb..dfbd550da0e 100644 --- a/src/dashboard/application/configuration/dashboard-configuration.php +++ b/src/dashboard/application/configuration/dashboard-configuration.php @@ -83,12 +83,12 @@ class Dashboard_Configuration { * @param Indexable_Helper $indexable_helper The indexable helper * repository. * @param User_Helper $user_helper The user helper. - * @param Enabled_Analysis_Features_Repository $enabled_analysis_features_repository The analysis feature - * @param Options_Helper $options_helper The options helper. - * @param Google_Site_Kit_Feature_Conditional $google_site_kit_conditional The Google Site Kit conditional. - * repository. + * @param Enabled_Analysis_Features_Repository $enabled_analysis_features_repository The analysis feature. + * repository. * @param Endpoints_Repository $endpoints_repository The endpoints repository. * @param Nonce_Repository $nonce_repository The nonce repository. + * @param Google_Site_Kit_Feature_Conditional $google_site_kit_conditional The Google Site Kit conditional. + * @param Options_Helper $options_helper The options helper. */ public function __construct( Content_Types_Repository $content_types_repository, @@ -132,6 +132,11 @@ public function get_configuration(): array { ]; } + /** + * Get the Google Site Kit configuration. + * + * @return array + */ public function get_google_site_kit_configuration(): array { $google_site_kit_file = 'google-site-kit/google-site-kit.php'; $google_site_kit_activate_url = \wp_nonce_url( From 7e9e03589ab5f40c22fb614bbbacc46a9226dc53 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 14:43:13 +0200 Subject: [PATCH 06/85] add the remove widget ui --- .../js/src/dashboard/components/dashboard.js | 12 +++++++- .../google-site-kit-connection-widget.js | 30 +++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index ad11f2a8929..e4241284e85 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -2,6 +2,8 @@ import { Scores } from "../scores/components/scores"; import { PageTitle } from "./page-title"; import { GoogleSiteKitConnectionWidget } from "./google-site-kit-connection-widget"; import { get } from "lodash"; +import { useCallback } from "@wordpress/element"; +import { useToggleState } from "@yoast/ui-library"; /** * @type {import("../index").ContentType} ContentType @@ -30,12 +32,20 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header activateUrl: "", setupUrl: "", } ); + const [ showGoogleSiteKit, , , , setRemoveGoogleSiteKit ] = useToggleState( true ); + + const handleRemovePermanently = useCallback( ()=>{ + setRemoveGoogleSiteKit(); + }, [ setRemoveGoogleSiteKit ] ); return ( <>
- { googleSiteKitConfiguration.featureActive && } + { showGoogleSiteKit && googleSiteKitConfiguration.featureActive && } { features.indexables && features.seoAnalysis && ( ) } diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index c30a71ad507..92755ecd394 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -1,10 +1,11 @@ -import { Button, Paper, Stepper, Title } from "@yoast/ui-library"; +import { Button, Paper, Stepper, Title, useToggleState } from "@yoast/ui-library"; import { ReactComponent as YoastConnectSiteKit } from "../../../images/yoast-connect-google-site-kit.svg"; import { __ } from "@wordpress/i18n"; import { CheckCircleIcon } from "@heroicons/react/solid"; -import { ArrowRightIcon } from "@heroicons/react/outline"; +import { ArrowRightIcon, DotsVerticalIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; import { useSelect } from "@wordpress/data"; import { addQueryArgs } from "@wordpress/url"; +import classNames from "classnames"; /** * Get the button and stepper props based on the current state. @@ -68,6 +69,8 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU * @param {boolean} installed Whether the plugin is installed. * @param {string} activateUrl The URL to activate Site Kit. * @param {string} installUrl The URL to install Site Kit. + * @param {function} onRemove The function to call when the widget is removed. + * @param {function} onRemovePermanently The function to call when the widget is removed permanently. * * @returns {JSX.Element} The widget. */ @@ -79,6 +82,8 @@ export const GoogleSiteKitConnectionWidget = ( { active, setup, installed, + onRemove, + onRemovePermanently, } ) => { const steps = [ { label: __( "INSTALL", "wordpress-seo" ) }, @@ -86,14 +91,29 @@ export const GoogleSiteKitConnectionWidget = ( { { label: __( "SET UP", "wordpress-seo" ) }, { label: __( "CONNECT", "wordpress-seo" ) }, ]; - + const [ open, toggleOpen ] = useToggleState( false ); const linkParams = useSelect( select => select( "@yoast/general" ).selectLinkParams(), [] ); const learnMorelink = addQueryArgs( "https://yoa.st/google-site-kit-learn-more", linkParams ); const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( active, installed, setup, connected, installUrl, activateUrl, setupUrl ); - return -
+ return +
+ + { open &&
+ + +
} +
+

{ __( "Expand your dashboard with insights from Google!", "wordpress-seo" ) } From 442008b90b79d5dd24709f7ec52d56e1298e9523 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 16:18:23 +0200 Subject: [PATCH 07/85] fix stepper labels colors --- packages/ui-library/src/elements/stepper/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/elements/stepper/style.css index 6717175d659..59b123c8dfa 100644 --- a/packages/ui-library/src/elements/stepper/style.css +++ b/packages/ui-library/src/elements/stepper/style.css @@ -21,8 +21,13 @@ .yst-step--active .yst-step-circle { @apply yst-bg-white yst-text-white yst-border-primary-500; } + + .yst-step--active { + @apply yst-text-primary-500; + } .yst-step--complete { + @apply yst-text-slate-900; .yst-step-circle { @apply yst-bg-primary-500 yst-text-white yst-border-primary-500; } From e9150b21a7746e510e4c6c369b47ea38c81a5b86 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 16:20:15 +0200 Subject: [PATCH 08/85] fix link and current step --- .../google-site-kit-connection-widget.js | 19 ++++++++++++------- .../configuration/dashboard-configuration.php | 6 +++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 92755ecd394..49599b4a496 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -21,15 +21,20 @@ import classNames from "classnames"; * @returns {Object} The button and stepper props. */ const getButtonAndStepperProps = ( active, installed, setup, connected, installUrl, activateUrl, setupUrl ) => { - let buttonProps = { - children: __( "Install Site Kit by Google", "wordpress-seo" ), - as: "a", - href: installUrl, - }; - let currentStep = 1; - let isComplete = false; + let buttonProps; + let currentStep; + let isComplete; switch ( true ) { + case ( ! installed ): + currentStep = 1; + isComplete = false; + buttonProps = { + children: __( "Install Site Kit by Google", "wordpress-seo" ), + as: "a", + href: installUrl, + }; + break; case ( ! active && installed ): currentStep = 2; buttonProps = { diff --git a/src/dashboard/application/configuration/dashboard-configuration.php b/src/dashboard/application/configuration/dashboard-configuration.php index dfbd550da0e..8264317c7a9 100644 --- a/src/dashboard/application/configuration/dashboard-configuration.php +++ b/src/dashboard/application/configuration/dashboard-configuration.php @@ -157,9 +157,9 @@ public function get_google_site_kit_configuration(): array { 'setup' => \get_option( 'googlesitekit_has_connected_admins', false ) === '1', 'connected' => $this->options_helper->get( 'google_site_kit_connected', false ), 'featureActive' => $this->google_site_kit_conditional->is_met(), - 'installUrl' => $google_site_kit_install_url, - 'activateUrl' => $google_site_kit_activate_url, - 'setupUrl' => $google_site_kit_setup_url, + 'installUrl' => \html_entity_decode( $google_site_kit_install_url ), + 'activateUrl' => \html_entity_decode( $google_site_kit_activate_url ), + 'setupUrl' => \html_entity_decode( $google_site_kit_setup_url ), ]; } } From ace94388ff7166d0d29319b0ac045c2f2c2cd5b1 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 16:30:41 +0200 Subject: [PATCH 09/85] fix padding in gsk widget --- .../google-site-kit-connection-widget.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 49599b4a496..ba2f8f83e80 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -102,22 +102,22 @@ export const GoogleSiteKitConnectionWidget = ( { const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( active, installed, setup, connected, installUrl, activateUrl, setupUrl ); - return -
- - { open &&
- - -
} -
+ return + + + { open &&
+ + +
} +

From 8a0c64ec2065c9bae914340225488504e31a8e39 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 20 Jan 2025 16:36:04 +0200 Subject: [PATCH 10/85] dd todo comments for permanently dismissing the widget --- packages/js/src/dashboard/components/dashboard.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index e4241284e85..0cedaef91cd 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -35,6 +35,7 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header const [ showGoogleSiteKit, , , , setRemoveGoogleSiteKit ] = useToggleState( true ); const handleRemovePermanently = useCallback( ()=>{ + // TODO: Implement the remove permanently functionality. setRemoveGoogleSiteKit(); }, [ setRemoveGoogleSiteKit ] ); From 2f3bf02b36c1fa221e16c6c5b554aeb965593bd0 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 21 Jan 2025 09:58:22 +0200 Subject: [PATCH 11/85] reduce eslint threshold and fix js lint --- packages/js/package.json | 2 +- packages/js/src/dashboard/components/dashboard.js | 4 ++++ .../dashboard/components/google-site-kit-connection-widget.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/js/package.json b/packages/js/package.json index 5f6d121ce15..8a3e08f4b7b 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "cd ../.. && wp-scripts build --config config/webpack/webpack.config.js", "test": "jest", - "lint": "eslint . --max-warnings=64" + "lint": "eslint . --max-warnings=63" }, "dependencies": { "@draft-js-plugins/mention": "^5.0.0", diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 0cedaef91cd..467d00a03c7 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -19,8 +19,11 @@ import { useToggleState } from "@yoast/ui-library"; * @param {Endpoints} endpoints The endpoints. * @param {Object} headers The headers for the score requests. * @param {Links} links The links. + * * @returns {JSX.Element} The element. */ +// The complexity is cause by the google site kit feature flag which is temporary. +// eslint-disable-next-line complexity export const Dashboard = ( { contentTypes, userName, features, endpoints, headers, links } ) => { const googleSiteKitConfiguration = get( window, "wpseoScriptData.dashboard.google_site_kit", { installed: false, @@ -35,6 +38,7 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header const [ showGoogleSiteKit, , , , setRemoveGoogleSiteKit ] = useToggleState( true ); const handleRemovePermanently = useCallback( ()=>{ + /* eslint-disable-next-line */ // TODO: Implement the remove permanently functionality. setRemoveGoogleSiteKit(); }, [ setRemoveGoogleSiteKit ] ); diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index ba2f8f83e80..bd1851ca8a3 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -35,7 +35,7 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU href: installUrl, }; break; - case ( ! active && installed ): + case ( ! active ): currentStep = 2; buttonProps = { children: __( "Activate Site Kit by Google", "wordpress-seo" ), From a95264858430c722cc1364e29ba164fbc48c8105 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 21 Jan 2025 11:05:04 +0200 Subject: [PATCH 12/85] add tests and fix accessibility --- .../google-site-kit-connection-widget.js | 42 ++++++++----- .../google-site-kit-connection-widget.test.js | 59 +++++++++++++++++++ 2 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index bd1851ca8a3..a088450d9d9 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -96,27 +96,39 @@ export const GoogleSiteKitConnectionWidget = ( { { label: __( "SET UP", "wordpress-seo" ) }, { label: __( "CONNECT", "wordpress-seo" ) }, ]; - const [ open, toggleOpen ] = useToggleState( false ); + const [ isMenuOpen, toggleMenuOpen ] = useToggleState( false ); const linkParams = useSelect( select => select( "@yoast/general" ).selectLinkParams(), [] ); const learnMorelink = addQueryArgs( "https://yoa.st/google-site-kit-learn-more", linkParams ); const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( active, installed, setup, connected, installUrl, activateUrl, setupUrl ); return - - - { open &&
- - -
} + + { isMenuOpen &&
    +
  • + +
  • +
  • + +
  • +
}
diff --git a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js b/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js new file mode 100644 index 00000000000..219e69a05db --- /dev/null +++ b/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js @@ -0,0 +1,59 @@ +import { render, screen, fireEvent } from "@testing-library/react"; +import { GoogleSiteKitConnectionWidget } from "../../../src/dashboard/components/google-site-kit-connection-widget"; + +jest.mock( "@wordpress/data", () => ( { + useSelect: jest.fn( () => [] ), +} ) ); + +describe( "GoogleSiteKitConnectionWidget", () => { + const defaultProps = { + installUrl: "https://example.com/install", + activateUrl: "https://example.com/activate", + setupUrl: "https://example.com/setup", + connected: false, + active: false, + setup: false, + installed: false, + onRemove: jest.fn(), + onRemovePermanently: jest.fn(), + }; + + it( "renders the widget with install button", () => { + render( ); + expect( screen.getByText( "Install Site Kit by Google" ) ).toBeInTheDocument(); + } ); + + it( "renders the widget with activate button", () => { + render( ); + expect( screen.getByText( "Activate Site Kit by Google" ) ).toBeInTheDocument(); + } ); + + it( "renders the widget with setup button", () => { + render( ); + expect( screen.getByText( "Set up Site Kit by Google" ) ).toBeInTheDocument(); + } ); + + it( "renders the widget with connect button", () => { + render( ); + expect( screen.getByText( "Connect Site Kit by Google" ) ).toBeInTheDocument(); + } ); + + it( "renders the widget with dismiss button when connected", () => { + render( ); + expect( screen.getByText( "Dismiss" ) ).toBeInTheDocument(); + } ); + + it( "opens the menu and calls onRemove when 'Remove until next visit' is clicked", () => { + render( ); + fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); + fireEvent.click( screen.getByText( "Remove until next visit" ) ); + expect( defaultProps.onRemove ).toHaveBeenCalled(); + } ); + + it( "opens the menu and calls onRemovePermanently when 'Remove permanently' is clicked", () => { + render( ); + fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); + fireEvent.click( screen.getByText( "Remove permanently" ) ); + expect( defaultProps.onRemovePermanently ).toHaveBeenCalled(); + } ); +} ); From d29b7481b318dd095b16e80b87c0c81f269c380f Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 21 Jan 2025 15:45:37 +0200 Subject: [PATCH 13/85] update svg --- .../images/yoast-connect-google-site-kit.svg | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/packages/js/images/yoast-connect-google-site-kit.svg b/packages/js/images/yoast-connect-google-site-kit.svg index 9cc11d73f58..ad3bfb2f879 100644 --- a/packages/js/images/yoast-connect-google-site-kit.svg +++ b/packages/js/images/yoast-connect-google-site-kit.svg @@ -1,22 +1,41 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + @@ -25,7 +44,7 @@ - + @@ -34,7 +53,7 @@ - + @@ -43,7 +62,7 @@ - + @@ -52,7 +71,7 @@ - + @@ -61,9 +80,11 @@ - + + + + - From aacdf7ee2ac9d1d76cf3f9bd4700c4a8f1759739 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 24 Jan 2025 13:46:42 +0200 Subject: [PATCH 14/85] fixed the links, buttons and isComplete --- .../google-site-kit-connection-widget.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index a088450d9d9..01685d3c156 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -4,7 +4,6 @@ import { __ } from "@wordpress/i18n"; import { CheckCircleIcon } from "@heroicons/react/solid"; import { ArrowRightIcon, DotsVerticalIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; import { useSelect } from "@wordpress/data"; -import { addQueryArgs } from "@wordpress/url"; import classNames from "classnames"; /** @@ -34,6 +33,7 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU as: "a", href: installUrl, }; + isComplete = false; break; case ( ! active ): currentStep = 2; @@ -42,6 +42,7 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU as: "a", href: activateUrl, }; + isComplete = false; break; case ( ! setup ): currentStep = 3; @@ -50,10 +51,12 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU as: "a", href: setupUrl, }; + isComplete = false; break; case ( ! connected ): currentStep = 4; buttonProps = { children: __( "Connect Site Kit by Google", "wordpress-seo" ) }; + isComplete = false; break; case connected: isComplete = true; @@ -97,8 +100,7 @@ export const GoogleSiteKitConnectionWidget = ( { { label: __( "CONNECT", "wordpress-seo" ) }, ]; const [ isMenuOpen, toggleMenuOpen ] = useToggleState( false ); - const linkParams = useSelect( select => select( "@yoast/general" ).selectLinkParams(), [] ); - const learnMorelink = addQueryArgs( "https://yoa.st/google-site-kit-learn-more", linkParams ); + const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( active, installed, setup, connected, installUrl, activateUrl, setupUrl ); @@ -119,14 +121,14 @@ export const GoogleSiteKitConnectionWidget = ( { { isMenuOpen &&
  • - + { __( "Remove until next visit", "wordpress-seo" ) }
  • - + { __( "Remove permanently", "wordpress-seo" ) }
} From f82bd8c541211082258aed81c441fbd784e51759 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 24 Jan 2025 14:05:36 +0200 Subject: [PATCH 15/85] rename props and fix isComplete variable --- .../js/src/dashboard/components/dashboard.js | 10 ++--- .../google-site-kit-connection-widget.js | 44 +++++++++---------- .../configuration/dashboard-configuration.php | 10 ++--- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 467d00a03c7..490404e08f1 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -26,14 +26,14 @@ import { useToggleState } from "@yoast/ui-library"; // eslint-disable-next-line complexity export const Dashboard = ( { contentTypes, userName, features, endpoints, headers, links } ) => { const googleSiteKitConfiguration = get( window, "wpseoScriptData.dashboard.google_site_kit", { - installed: false, - featureActive: false, - active: false, - setup: false, - connected: false, + isInstalled: false, + isActive: false, + isSetup: false, + isConnected: false, installUrl: "", activateUrl: "", setupUrl: "", + featureActive: false, } ); const [ showGoogleSiteKit, , , , setRemoveGoogleSiteKit ] = useToggleState( true ); diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 01685d3c156..880635db62c 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -9,23 +9,23 @@ import classNames from "classnames"; /** * Get the button and stepper props based on the current state. * - * @param {boolean} active Whether the feature is active. - * @param {boolean} installed Whether the plugin is installed. - * @param {boolean} setup Whether the setup is complete. - * @param {boolean} connected Whether the connection is active. + * @param {boolean} isInstalled Whether the plugin is isInstalled. + * @param {boolean} isActive Whether the feature is active. + * @param {boolean} isSetup Whether the setup is complete. + * @param {boolean} isConnected Whether the connection is active. * @param {string} installUrl The URL to install Site Kit. * @param {string} activateUrl The URL to activate Site Kit. * @param {string} setupUrl The URL to setup Site Kit. * * @returns {Object} The button and stepper props. */ -const getButtonAndStepperProps = ( active, installed, setup, connected, installUrl, activateUrl, setupUrl ) => { +const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ) => { let buttonProps; let currentStep; let isComplete; switch ( true ) { - case ( ! installed ): + case ( ! isInstalled ): currentStep = 1; isComplete = false; buttonProps = { @@ -35,7 +35,7 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU }; isComplete = false; break; - case ( ! active ): + case ( ! isActive ): currentStep = 2; buttonProps = { children: __( "Activate Site Kit by Google", "wordpress-seo" ), @@ -44,7 +44,7 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU }; isComplete = false; break; - case ( ! setup ): + case ( ! isSetup ): currentStep = 3; buttonProps = { children: __( "Set up Site Kit by Google", "wordpress-seo" ), @@ -53,12 +53,12 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU }; isComplete = false; break; - case ( ! connected ): + case ( ! isConnected ): currentStep = 4; buttonProps = { children: __( "Connect Site Kit by Google", "wordpress-seo" ) }; isComplete = false; break; - case connected: + case isConnected: isComplete = true; currentStep = 4; buttonProps = { children: "Take a quick tour" }; @@ -70,13 +70,13 @@ const getButtonAndStepperProps = ( active, installed, setup, connected, installU /** * The google site kit connection guide widget. * - * @param {boolean} installed Whether the plugin is installed. - * @param {boolean} setup Whether the setup is complete. - * @param {boolean} active Whether the feature is active. - * @param {boolean} connected Whether the connection is active. - * @param {boolean} installed Whether the plugin is installed. - * @param {string} activateUrl The URL to activate Site Kit. + * @param {boolean} isInstalled Whether the plugin is installed. + * @param {boolean} isActive Whether the feature is active. + * @param {boolean} isSetup Whether the setup is complete. + * @param {boolean} isConnected Whether the connection is active. * @param {string} installUrl The URL to install Site Kit. + * @param {string} activateUrl The URL to activate Site Kit. + * @param {string} setupUrl The URL to setup Site Kit. * @param {function} onRemove The function to call when the widget is removed. * @param {function} onRemovePermanently The function to call when the widget is removed permanently. * @@ -86,10 +86,10 @@ export const GoogleSiteKitConnectionWidget = ( { installUrl, activateUrl, setupUrl, - connected, - active, - setup, - installed, + isConnected, + isActive, + isSetup, + isInstalled, onRemove, onRemovePermanently, } ) => { @@ -103,7 +103,7 @@ export const GoogleSiteKitConnectionWidget = ( { const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( - active, installed, setup, connected, installUrl, activateUrl, setupUrl ); + isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ); return + { isConnected ? : diff --git a/src/dashboard/application/configuration/dashboard-configuration.php b/src/dashboard/application/configuration/dashboard-configuration.php index 8264317c7a9..68c30ca1413 100644 --- a/src/dashboard/application/configuration/dashboard-configuration.php +++ b/src/dashboard/application/configuration/dashboard-configuration.php @@ -152,14 +152,14 @@ public function get_google_site_kit_configuration(): array { $google_site_kit_setup_url = \self_admin_url( 'admin.php?page=googlesitekit-splash' ); return [ - 'installed' => \file_exists( \WP_PLUGIN_DIR . '/' . $google_site_kit_file ), - 'active' => \is_plugin_active( $google_site_kit_file ), - 'setup' => \get_option( 'googlesitekit_has_connected_admins', false ) === '1', - 'connected' => $this->options_helper->get( 'google_site_kit_connected', false ), - 'featureActive' => $this->google_site_kit_conditional->is_met(), + 'isInstalled' => \file_exists( \WP_PLUGIN_DIR . '/' . $google_site_kit_file ), + 'isActive' => \is_plugin_active( $google_site_kit_file ), + 'isSetup' => \get_option( 'googlesitekit_has_connected_admins', false ) === '1', + 'isConnected' => $this->options_helper->get( 'google_site_kit_connected', false ), 'installUrl' => \html_entity_decode( $google_site_kit_install_url ), 'activateUrl' => \html_entity_decode( $google_site_kit_activate_url ), 'setupUrl' => \html_entity_decode( $google_site_kit_setup_url ), + 'featureActive' => $this->google_site_kit_conditional->is_met(), ]; } } From cc9cfa8a1b08814a19e222854e1db6efd7f524a1 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 24 Jan 2025 15:43:05 +0200 Subject: [PATCH 16/85] fix is complete --- .../components/google-site-kit-connection-widget.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 880635db62c..15f9c4d884f 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -22,18 +22,16 @@ import classNames from "classnames"; const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ) => { let buttonProps; let currentStep; - let isComplete; + let isComplete = false; switch ( true ) { case ( ! isInstalled ): currentStep = 1; - isComplete = false; buttonProps = { children: __( "Install Site Kit by Google", "wordpress-seo" ), as: "a", href: installUrl, }; - isComplete = false; break; case ( ! isActive ): currentStep = 2; @@ -42,7 +40,6 @@ const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, as: "a", href: activateUrl, }; - isComplete = false; break; case ( ! isSetup ): currentStep = 3; @@ -51,12 +48,10 @@ const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, as: "a", href: setupUrl, }; - isComplete = false; break; case ( ! isConnected ): currentStep = 4; buttonProps = { children: __( "Connect Site Kit by Google", "wordpress-seo" ) }; - isComplete = false; break; case isConnected: isComplete = true; From 37e38aef9038f7c1436cd51fa50c3464895f3f2e Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 24 Jan 2025 16:26:25 +0200 Subject: [PATCH 17/85] simplify step and add animation to progress bar --- packages/ui-library/src/elements/stepper/index.js | 6 ++---- packages/ui-library/src/elements/stepper/style.css | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 20cebc0b8ae..f85e3b443c6 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -28,9 +28,7 @@ const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => {
{ ( currentStep > index + 1 || isComplete ) && } - { ! isComplete && currentStep === index + 1 && - - } + { ! isComplete && currentStep === index + 1 &&
}
{ label }
@@ -101,7 +99,7 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } { /* Progress */ }
diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/elements/stepper/style.css index 59b123c8dfa..8b501cb5906 100644 --- a/packages/ui-library/src/elements/stepper/style.css +++ b/packages/ui-library/src/elements/stepper/style.css @@ -7,10 +7,10 @@ .yst-step-circle { @apply yst-bg-white - yst-border-slate-300 + yst-ring-slate-300 yst-w-6 yst-h-6 - yst-border-2 + yst-ring-2 yst-rounded-full yst-flex yst-items-center @@ -19,7 +19,7 @@ } .yst-step--active .yst-step-circle { - @apply yst-bg-white yst-text-white yst-border-primary-500; + @apply yst-bg-white yst-text-white yst-ring-primary-500; } .yst-step--active { @@ -29,7 +29,7 @@ .yst-step--complete { @apply yst-text-slate-900; .yst-step-circle { - @apply yst-bg-primary-500 yst-text-white yst-border-primary-500; + @apply yst-bg-primary-500 yst-text-white yst-ring-primary-500; } } From 42ddef43586ed745fc45ad1fecbb1a2ff4133e38 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 24 Jan 2025 16:44:08 +0200 Subject: [PATCH 18/85] fix check icon size and animation --- packages/ui-library/src/elements/stepper/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index f85e3b443c6..045ae32ec2f 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -26,7 +26,7 @@ const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => { currentStep === index + 1 ? "yst-step--active" : "" ) } >
- { ( currentStep > index + 1 || isComplete ) && } + { ( currentStep > index + 1 || isComplete ) && } { ! isComplete && currentStep === index + 1 &&
}
@@ -99,7 +99,7 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } { /* Progress */ }
From 7bb273dfdb210c672741a3640f846d8519df4014 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 24 Jan 2025 23:36:10 +0200 Subject: [PATCH 19/85] fix stepper animation --- packages/ui-library/src/elements/stepper/index.js | 14 +++++++++++--- packages/ui-library/src/elements/stepper/style.css | 11 ++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 045ae32ec2f..e2b3da4c929 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -26,9 +26,17 @@ const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => { currentStep === index + 1 ? "yst-step--active" : "" ) } >
- { ( currentStep > index + 1 || isComplete ) && } + index + 1 || isComplete ) ? "yst-opacity-100" : "yst-opacity-0" ) } + /> - { ! isComplete && currentStep === index + 1 &&
} +
{ label }
@@ -99,7 +107,7 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } { /* Progress */ }
diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/elements/stepper/style.css index 8b501cb5906..e8fcf84fb25 100644 --- a/packages/ui-library/src/elements/stepper/style.css +++ b/packages/ui-library/src/elements/stepper/style.css @@ -12,12 +12,17 @@ yst-h-6 yst-ring-2 yst-rounded-full - yst-flex - yst-items-center - yst-justify-center + yst-relative + yst-transition-all + yst-ease-in + yst-delay-500 yst-z-10; } + .yst-step-icon { + @apply yst-absolute yst-top-1/2 yst-left-1/2 yst-transform -yst-translate-x-1/2 -yst-translate-y-1/2 yst-transition-all yst-ease-in; + } + .yst-step--active .yst-step-circle { @apply yst-bg-white yst-text-white yst-ring-primary-500; } From 937da2cc00aa2072e4135d9e69ec23641a2749cd Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 27 Jan 2025 10:13:24 +0200 Subject: [PATCH 20/85] fix stepper order of animation --- .../ui-library/src/elements/stepper/index.js | 14 +++---- .../ui-library/src/elements/stepper/style.css | 40 ++++++++++++------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index e2b3da4c929..7a42dd72246 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -21,20 +21,18 @@ const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => { return (
index + 1 || isComplete ? "yst-step--complete" : "", currentStep === index + 1 ? "yst-step--active" : "" ) } > -
- index + 1 || isComplete ) ? "yst-opacity-100" : "yst-opacity-0" ) } - /> +
+ { ( currentStep > index + 1 || isComplete ) && }
diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/elements/stepper/style.css index e8fcf84fb25..1f963aaf6af 100644 --- a/packages/ui-library/src/elements/stepper/style.css +++ b/packages/ui-library/src/elements/stepper/style.css @@ -3,38 +3,50 @@ .yst-stepper { @apply yst-relative yst-flex yst-justify-between yst-items-center; + + } + + .yst-step { + @apply yst-flex yst-flex-col yst-items-center; } - .yst-step-circle { + .yst-step__circle { @apply yst-bg-white yst-ring-slate-300 yst-w-6 yst-h-6 yst-ring-2 yst-rounded-full - yst-relative - yst-transition-all - yst-ease-in - yst-delay-500 - yst-z-10; - } - - .yst-step-icon { - @apply yst-absolute yst-top-1/2 yst-left-1/2 yst-transform -yst-translate-x-1/2 -yst-translate-y-1/2 yst-transition-all yst-ease-in; + yst-z-10 + yst-relative; } - .yst-step--active .yst-step-circle { - @apply yst-bg-white yst-text-white yst-ring-primary-500; + .yst-step__icon { + @apply yst-absolute yst-top-1/2 yst-left-1/2 yst-transform -yst-translate-x-1/2 -yst-translate-y-1/2; } .yst-step--active { @apply yst-text-primary-500; + + .yst-step__circle { + @apply + yst-bg-white + yst-text-white + yst-ring-primary-500 + yst-transition-all + yst-ease-in + yst-delay-500; + } + + .yst-step__icon{ + @apply yst-transition-all yst-ease-in; + } } .yst-step--complete { @apply yst-text-slate-900; - .yst-step-circle { - @apply yst-bg-primary-500 yst-text-white yst-ring-primary-500; + .yst-step__circle { + @apply yst-bg-primary-500 yst-text-white yst-ring-primary-500 yst-transition-none yst-delay-0; } } From ec0318b8a7363baa1d468433436331168bb7cb7c Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Mon, 27 Jan 2025 15:13:32 +0200 Subject: [PATCH 21/85] fix stepper Changed the steps to string, and cached the complete state --- .../google-site-kit-connection-widget.js | 13 +++++++------ packages/ui-library/src/elements/stepper/index.js | 15 ++++++++------- .../ui-library/src/elements/stepper/stories.js | 15 +-------------- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 15f9c4d884f..53761e18cdb 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -62,6 +62,13 @@ const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, return { buttonProps, currentStep, isComplete }; }; +const steps = [ + __( "INSTALL", "wordpress-seo" ), + __( "ACTIVATE", "wordpress-seo" ), + __( "SET UP", "wordpress-seo" ), + __( "CONNECT", "wordpress-seo" ), +]; + /** * The google site kit connection guide widget. * @@ -88,12 +95,6 @@ export const GoogleSiteKitConnectionWidget = ( { onRemove, onRemovePermanently, } ) => { - const steps = [ - { label: __( "INSTALL", "wordpress-seo" ) }, - { label: __( "ACTIVATE", "wordpress-seo" ) }, - { label: __( "SET UP", "wordpress-seo" ) }, - { label: __( "CONNECT", "wordpress-seo" ) }, - ]; const [ isMenuOpen, toggleMenuOpen ] = useToggleState( false ); const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 7a42dd72246..9543946dcff 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -18,15 +18,18 @@ const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => { const handleRef = useCallback( ( el ) =>{ addStepRef( el, index ); }, [] ); + + const isStepComplete = currentStep > index + 1 || isComplete; + return (
index + 1 || isComplete ? "yst-step--complete" : "", + isStepComplete ? "yst-step--complete" : "", currentStep === index + 1 ? "yst-step--active" : "" ) } >
- { ( currentStep > index + 1 || isComplete ) && } @@ -84,8 +87,8 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } return (
{ steps.map( ( step, index ) => Date: Mon, 27 Jan 2025 17:21:15 +0200 Subject: [PATCH 22/85] added the dropdown menu --- packages/ui-library/.storybook/style.css | 1 + .../dropdown-menu/docs/component.md | 1 + .../components/dropdown-menu/docs/index.js | 1 + .../src/components/dropdown-menu/index.js | 85 +++++++++++++++++++ .../src/components/dropdown-menu/stories.js | 52 ++++++++++++ .../src/components/dropdown-menu/style.css | 60 +++++++++++++ packages/ui-library/src/index.js | 1 + 7 files changed, 201 insertions(+) create mode 100644 packages/ui-library/src/components/dropdown-menu/docs/component.md create mode 100644 packages/ui-library/src/components/dropdown-menu/docs/index.js create mode 100644 packages/ui-library/src/components/dropdown-menu/index.js create mode 100644 packages/ui-library/src/components/dropdown-menu/stories.js create mode 100644 packages/ui-library/src/components/dropdown-menu/style.css diff --git a/packages/ui-library/.storybook/style.css b/packages/ui-library/.storybook/style.css index fa96907fa11..54575456cc4 100644 --- a/packages/ui-library/.storybook/style.css +++ b/packages/ui-library/.storybook/style.css @@ -40,6 +40,7 @@ @import "../src/components/textarea-field/style.css"; @import "../src/components/toggle-field/style.css"; @import "../src/components/tooltip-container/style.css"; +@import "../src/components/dropdown-menu/style.css"; @tailwind base; @tailwind components; diff --git a/packages/ui-library/src/components/dropdown-menu/docs/component.md b/packages/ui-library/src/components/dropdown-menu/docs/component.md new file mode 100644 index 00000000000..6d28275cac2 --- /dev/null +++ b/packages/ui-library/src/components/dropdown-menu/docs/component.md @@ -0,0 +1 @@ +A dropdowm menu with menu item and button item sub components. The menu trigger accepts a node and fallback to three vertical dots if not provided. diff --git a/packages/ui-library/src/components/dropdown-menu/docs/index.js b/packages/ui-library/src/components/dropdown-menu/docs/index.js new file mode 100644 index 00000000000..a01392a1542 --- /dev/null +++ b/packages/ui-library/src/components/dropdown-menu/docs/index.js @@ -0,0 +1 @@ +export { default as component } from "./component.md"; diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js new file mode 100644 index 00000000000..8a95e3d9ea3 --- /dev/null +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -0,0 +1,85 @@ +import { DotsVerticalIcon } from "@heroicons/react/outline"; +import classNames from "classnames"; +import PropTypes from "prop-types"; +import React, { Fragment } from "react"; +import { Menu, Transition } from "@headlessui/react"; +import { Button } from "../../index"; + +/** + * The button Item for the dropdown menu. + * + * + * @param {JSX.node} children Content of the button. + * @param {string} [className] CSS class. + * + * @returns {JSX.Element} Button component. + */ +const MenuButtonItem = ( { children, className, ...props } ) => { + return ( + + { children } + + + ); +}; + +MenuButtonItem.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, +}; + +/** + * + * @param {JSX.node} children Content of the menu. + * @param {JSX.node} [menuButtonContent] Content of the menu button. + * @param {string} [className] CSS class. + * @returns + */ +export const DropdownMenu = ( { children, menuTrigger, screenReaderTriggerLabel = "Open menu", className } ) => { + return ( + + { menuTrigger + ? + : + + { screenReaderTriggerLabel } + } + + + { children } + + + + ); +}; + +DropdownMenu.propTypes = { + children: PropTypes.node.isRequired, + menuTrigger: PropTypes.node, + screenReaderTriggerLabel: PropTypes.string, + className: PropTypes.string, +}; + +DropdownMenu.Item = Menu.Item; +DropdownMenu.Item.displayName = "DropdownMenu.Item"; + +DropdownMenu.ButtonItem = MenuButtonItem; +DropdownMenu.ButtonItem.displayName = "DropdownMenu.ButtonItem"; + +DropdownMenu.displayName = "DropdownMenu"; diff --git a/packages/ui-library/src/components/dropdown-menu/stories.js b/packages/ui-library/src/components/dropdown-menu/stories.js new file mode 100644 index 00000000000..b8bda9a0586 --- /dev/null +++ b/packages/ui-library/src/components/dropdown-menu/stories.js @@ -0,0 +1,52 @@ +import { DropdownMenu } from "."; +import React from "react"; +import { XIcon, TrashIcon } from "@heroicons/react/outline"; +import { component } from "./docs"; + +export const Factory = { + render: ( args ) => , + args: { + children: ( + <> + + Item + + + Item + + + + Button Item + + + + Button Item + + + ), + screenReaderTriggerLabel: "Open menu", + }, +}; + + +export default { + title: "2) Components/DropdownMenu", + component: DropdownMenu, + argTypes: { + children: { control: "text" }, + screenReaderTriggerLabel: { control: "text" }, + menuTrigger: { control: "text" }, + }, + parameters: { + docs: { + description: { component }, + }, + }, + decorators: [ + ( Story ) => ( +
+ +
+ ), + ], +}; diff --git a/packages/ui-library/src/components/dropdown-menu/style.css b/packages/ui-library/src/components/dropdown-menu/style.css new file mode 100644 index 00000000000..98fcacdc771 --- /dev/null +++ b/packages/ui-library/src/components/dropdown-menu/style.css @@ -0,0 +1,60 @@ +@layer components { + .yst-root { + .yst-dropdown-menu__button { + @apply + yst-absolute + yst-top-4 + yst-end-4 + yst-p-0 + yst-text-slate-400 + yst-rounded-full + focus:yst-text-slate-600 + focus:yst-outline + focus:yst-outline-2 + focus:yst-outline-offset-2 + focus:yst-outline-primary-500; + } + + .yst-dropdown-menu__item { + @apply + yst-border-b + yst-border-slate-200 + last:yst-border-0 + yst-text-slate-600; + } + + .yst-dropdown-menu__item--button{ + @apply + yst-flex + yst-py-2 + yst-justify-start + yst-gap-2 yst-px-4 + yst-items-center + yst-w-full + yst-ring-0 + yst-rounded-none + focus:yst-outline-none + focus:yst-bg-slate-100 + hover:yst-bg-slate-100 + yst-outline-none; + } + + .yst-dropdown-menu { + @apply yst-relative; + } + + .yst-dropdown-menu__list { + @apply + yst-w-56 + yst-rounded-md + yst-border + yst-border-slate-200 + yst-shadow-sm + yst-bg-white + yst-absolute + yst-top-10 + yst-end-4 + focus-visible:yst-outline-none; + } + } +} \ No newline at end of file diff --git a/packages/ui-library/src/index.js b/packages/ui-library/src/index.js index 4c9b7f978fc..d2ca7a6ccfb 100644 --- a/packages/ui-library/src/index.js +++ b/packages/ui-library/src/index.js @@ -42,6 +42,7 @@ export { default as TextField } from "./components/text-field"; export { default as TextareaField } from "./components/textarea-field"; export { default as ToggleField } from "./components/toggle-field"; export { TooltipContainer, TooltipTrigger, TooltipWithContext, useTooltipContext } from "./components/tooltip-container"; +export { DropdownMenu } from "./components/dropdown-menu"; export * from "./hooks"; export * from "./constants"; From 719f0c91e3669b14a7e7c4940e00196b1913a664 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 14:19:50 +0200 Subject: [PATCH 23/85] fix dropdown menu --- .../src/components/dropdown-menu/index.js | 92 +++++++++++++------ .../src/components/dropdown-menu/stories.js | 43 ++++----- .../src/components/dropdown-menu/style.css | 15 +-- 3 files changed, 88 insertions(+), 62 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 8a95e3d9ea3..19a1c04fefd 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -8,7 +8,6 @@ import { Button } from "../../index"; /** * The button Item for the dropdown menu. * - * * @param {JSX.node} children Content of the button. * @param {string} [className] CSS class. * @@ -34,45 +33,77 @@ MenuButtonItem.propTypes = { className: PropTypes.string, }; +/** + * Dropdown menu icon trigger. + * + * @param {string} [className] CSS class. + * @param {string} [screenReaderTriggerLabel] Screen reader label. + * @param {JSX.node} [Icon] Icon component. + * + * @returns {JSX.Element} Menu trigger component. + */ +const DropdownMenuIconTrigger = ( { className, screenReaderTriggerLabel = "Open menu", Icon = DotsVerticalIcon, ...props } ) => ( + + + { screenReaderTriggerLabel } + + +); + +DropdownMenuIconTrigger.propTypes = { + className: PropTypes.string, + screenReaderTriggerLabel: PropTypes.string, + Icon: PropTypes.node, +}; + +/** + * Dropdown menu list. + * + * @param {JSX.node} children Content of the menu. + * + * @returns {JSX.Element} Menu component. + */ +const DropdownMenuList = ( { children, className } ) => { + return ( + + + { children } + + + ); +}; + +DropdownMenuList.propTypes = { + children: PropTypes.node.isRequired, + className: PropTypes.string, +}; + /** * * @param {JSX.node} children Content of the menu. - * @param {JSX.node} [menuButtonContent] Content of the menu button. * @param {string} [className] CSS class. * @returns */ -export const DropdownMenu = ( { children, menuTrigger, screenReaderTriggerLabel = "Open menu", className } ) => { +export const DropdownMenu = ( { children, className } ) => { return ( - { menuTrigger - ? - : - - { screenReaderTriggerLabel } - } - - - { children } - - + { children } ); }; DropdownMenu.propTypes = { children: PropTypes.node.isRequired, - menuTrigger: PropTypes.node, - screenReaderTriggerLabel: PropTypes.string, className: PropTypes.string, }; @@ -82,4 +113,13 @@ DropdownMenu.Item.displayName = "DropdownMenu.Item"; DropdownMenu.ButtonItem = MenuButtonItem; DropdownMenu.ButtonItem.displayName = "DropdownMenu.ButtonItem"; +DropdownMenu.IconTrigger = DropdownMenuIconTrigger; +DropdownMenu.IconTrigger.displayName = "DropdownMenu.IconTrigger"; + +DropdownMenu.Trigger = Menu.Button; +DropdownMenu.Trigger.displayName = "DropdownMenu.Trigger"; + +DropdownMenu.List = DropdownMenuList; +DropdownMenu.List.displayName = "DropdownMenu.List"; + DropdownMenu.displayName = "DropdownMenu"; diff --git a/packages/ui-library/src/components/dropdown-menu/stories.js b/packages/ui-library/src/components/dropdown-menu/stories.js index b8bda9a0586..33c74fdf91b 100644 --- a/packages/ui-library/src/components/dropdown-menu/stories.js +++ b/packages/ui-library/src/components/dropdown-menu/stories.js @@ -4,28 +4,25 @@ import { XIcon, TrashIcon } from "@heroicons/react/outline"; import { component } from "./docs"; export const Factory = { - render: ( args ) => , - args: { - children: ( - <> - - Item - - - Item - - - - Button Item - - - - Button Item - - - ), - screenReaderTriggerLabel: "Open menu", - }, + render: () => + + + + Item + + + Item + + + + Button Item + + + + Button Item + + + , }; @@ -34,8 +31,6 @@ export default { component: DropdownMenu, argTypes: { children: { control: "text" }, - screenReaderTriggerLabel: { control: "text" }, - menuTrigger: { control: "text" }, }, parameters: { docs: { diff --git a/packages/ui-library/src/components/dropdown-menu/style.css b/packages/ui-library/src/components/dropdown-menu/style.css index 98fcacdc771..97a38fcf846 100644 --- a/packages/ui-library/src/components/dropdown-menu/style.css +++ b/packages/ui-library/src/components/dropdown-menu/style.css @@ -1,10 +1,7 @@ @layer components { .yst-root { - .yst-dropdown-menu__button { + .yst-dropdown-menu__icon-trigger { @apply - yst-absolute - yst-top-4 - yst-end-4 yst-p-0 yst-text-slate-400 yst-rounded-full @@ -23,7 +20,7 @@ yst-text-slate-600; } - .yst-dropdown-menu__item--button{ + .yst-dropdown-menu__item--button { @apply yst-flex yst-py-2 @@ -39,10 +36,6 @@ yst-outline-none; } - .yst-dropdown-menu { - @apply yst-relative; - } - .yst-dropdown-menu__list { @apply yst-w-56 @@ -51,9 +44,7 @@ yst-border-slate-200 yst-shadow-sm yst-bg-white - yst-absolute - yst-top-10 - yst-end-4 + yst-z-50 focus-visible:yst-outline-none; } } From 1600141684b10402cb6f7a90cdcf4b65e6484ce8 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 14:20:03 +0200 Subject: [PATCH 24/85] implement dropdown menu --- .../google-site-kit-connection-widget.js | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index 53761e18cdb..acc5ca83682 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -1,10 +1,9 @@ -import { Button, Paper, Stepper, Title, useToggleState } from "@yoast/ui-library"; +import { Button, Paper, Stepper, Title, DropdownMenu } from "@yoast/ui-library"; import { ReactComponent as YoastConnectSiteKit } from "../../../images/yoast-connect-google-site-kit.svg"; import { __ } from "@wordpress/i18n"; import { CheckCircleIcon } from "@heroicons/react/solid"; -import { ArrowRightIcon, DotsVerticalIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; +import { ArrowRightIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; import { useSelect } from "@wordpress/data"; -import classNames from "classnames"; /** * Get the button and stepper props based on the current state. @@ -95,38 +94,25 @@ export const GoogleSiteKitConnectionWidget = ( { onRemove, onRemovePermanently, } ) => { - const [ isMenuOpen, toggleMenuOpen ] = useToggleState( false ); const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ); return - - { isMenuOpen &&
    -
  • - -
  • -
  • - -
  • -
} + { __( "Remove permanently", "wordpress-seo" ) } + + +
From 5dda8d594e4b31a538f977d6b85606a9867b54a1 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 14:23:14 +0200 Subject: [PATCH 25/85] Switch to camel case camel case in js --- packages/js/src/dashboard/components/dashboard.js | 2 +- .../application/configuration/dashboard-configuration.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 490404e08f1..378f1b0cde4 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -25,7 +25,7 @@ import { useToggleState } from "@yoast/ui-library"; // The complexity is cause by the google site kit feature flag which is temporary. // eslint-disable-next-line complexity export const Dashboard = ( { contentTypes, userName, features, endpoints, headers, links } ) => { - const googleSiteKitConfiguration = get( window, "wpseoScriptData.dashboard.google_site_kit", { + const googleSiteKitConfiguration = get( window, "wpseoScriptData.dashboard.googleSiteKit", { isInstalled: false, isActive: false, isSetup: false, diff --git a/src/dashboard/application/configuration/dashboard-configuration.php b/src/dashboard/application/configuration/dashboard-configuration.php index 68c30ca1413..e7782be528f 100644 --- a/src/dashboard/application/configuration/dashboard-configuration.php +++ b/src/dashboard/application/configuration/dashboard-configuration.php @@ -128,7 +128,7 @@ public function get_configuration(): array { )->to_array(), 'endpoints' => $this->endpoints_repository->get_all_endpoints()->to_array(), 'nonce' => $this->nonce_repository->get_rest_nonce(), - 'google_site_kit' => $this->get_google_site_kit_configuration(), + 'googleSiteKit' => $this->get_google_site_kit_configuration(), ]; } From 45f936c58462ce29f1e0797095fe7ba1984cf54e Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 14:26:52 +0200 Subject: [PATCH 26/85] fix php cs --- .../configuration/dashboard-configuration.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dashboard/application/configuration/dashboard-configuration.php b/src/dashboard/application/configuration/dashboard-configuration.php index e7782be528f..1314b0572c4 100644 --- a/src/dashboard/application/configuration/dashboard-configuration.php +++ b/src/dashboard/application/configuration/dashboard-configuration.php @@ -128,7 +128,7 @@ public function get_configuration(): array { )->to_array(), 'endpoints' => $this->endpoints_repository->get_all_endpoints()->to_array(), 'nonce' => $this->nonce_repository->get_rest_nonce(), - 'googleSiteKit' => $this->get_google_site_kit_configuration(), + 'googleSiteKit' => $this->get_google_site_kit_configuration(), ]; } @@ -156,10 +156,10 @@ public function get_google_site_kit_configuration(): array { 'isActive' => \is_plugin_active( $google_site_kit_file ), 'isSetup' => \get_option( 'googlesitekit_has_connected_admins', false ) === '1', 'isConnected' => $this->options_helper->get( 'google_site_kit_connected', false ), - 'installUrl' => \html_entity_decode( $google_site_kit_install_url ), - 'activateUrl' => \html_entity_decode( $google_site_kit_activate_url ), - 'setupUrl' => \html_entity_decode( $google_site_kit_setup_url ), - 'featureActive' => $this->google_site_kit_conditional->is_met(), + 'installUrl' => \html_entity_decode( $google_site_kit_install_url ), + 'activateUrl' => \html_entity_decode( $google_site_kit_activate_url ), + 'setupUrl' => \html_entity_decode( $google_site_kit_setup_url ), + 'featureActive' => $this->google_site_kit_conditional->is_met(), ]; } } From 423398c6d921de49a8d04f1a5b1e4858ef5766a9 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 14:52:50 +0200 Subject: [PATCH 27/85] refactor step --- .../ui-library/src/elements/stepper/index.js | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 9543946dcff..cef12a201b8 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -14,19 +14,13 @@ import { CheckIcon } from "@heroicons/react/solid"; * * @returns {JSX.Element} The step element. */ -const Step = ( { label, index, isComplete, currentStep, addStepRef } ) => { - const handleRef = useCallback( ( el ) =>{ - addStepRef( el, index ); - }, [] ); - - const isStepComplete = currentStep > index + 1 || isComplete; - +const Step = forwardRef( ( { label, isComplete, isActive, isStepComplete }, ref ) => { return (
{ isStepComplete && {
{ label }
); -}; +} ); +Step.displayName = "Step"; Step.propTypes = { label: PropTypes.string.isRequired, - index: PropTypes.number.isRequired, isComplete: PropTypes.bool.isRequired, - currentStep: PropTypes.number.isRequired, - addStepRef: PropTypes.func.isRequired, + isStepComplete: PropTypes.bool.isRequired, + isActive: PropTypes.bool.isRequired, }; /** @@ -58,6 +52,7 @@ Step.propTypes = { * @param {boolean} isComplete Is the step complete. * @param {array} steps The steps names. * @param {string} [className] Optional extra className. + * * @returns {JSX.Element} The Stepper element. */ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" }, ref ) => { @@ -72,17 +67,17 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } marginLeft: stepRef.current[ 0 ].offsetWidth / 2, marginRight: stepRef.current[ steps.length - 1 ].offsetWidth / 2, } ); - }, [ stepRef, steps.length ] ); + }, [ stepRef.current, steps.length ] ); if ( ! steps.length ) { - return <>; + return; } const calculateProgressBarWidth = () => { return ( ( currentStep - 1 ) / ( steps.length - 1 ) ) * 100; }; - const addStepRef = useCallback( ( el, index ) => ( stepRef.current[ index ] = el ), [ stepRef ] ); + const addStepRef = useCallback( ( el ) => ( stepRef.current.push( el ) ), [ stepRef.current ] ); return (
@@ -92,7 +87,9 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } currentStep={ currentStep } isComplete={ isComplete } index={ index } - addStepRef={ addStepRef } + isActive={ currentStep === index + 1 } + isStepComplete={ currentStep > index + 1 || isComplete } + ref={ addStepRef } /> ) } { /* Progress bar */ } From 53aaa0bf76a18ef55da471b7add040d5c6de12a4 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 15:01:43 +0200 Subject: [PATCH 28/85] use ui library progress bar in stepper --- .../ui-library/src/elements/stepper/index.js | 29 +++++-------------- .../ui-library/src/elements/stepper/style.css | 5 +++- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index cef12a201b8..b0525e3e78e 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -2,6 +2,7 @@ import classNames from "classnames"; import PropTypes from "prop-types"; import React, { forwardRef, useRef, useEffect, useState, useCallback } from "react"; import { CheckIcon } from "@heroicons/react/solid"; +import { ProgressBar } from "../../index"; /** * Step component. @@ -73,10 +74,6 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } return; } - const calculateProgressBarWidth = () => { - return ( ( currentStep - 1 ) / ( steps.length - 1 ) ) * 100; - }; - const addStepRef = useCallback( ( el ) => ( stepRef.current.push( el ) ), [ stepRef.current ] ); return ( @@ -92,23 +89,13 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } ref={ addStepRef } /> ) } - { /* Progress bar */ } -
- - { /* Progress */ } -
-
+
); diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/elements/stepper/style.css index 1f963aaf6af..139e0a3eea8 100644 --- a/packages/ui-library/src/elements/stepper/style.css +++ b/packages/ui-library/src/elements/stepper/style.css @@ -4,6 +4,10 @@ .yst-stepper { @apply yst-relative yst-flex yst-justify-between yst-items-center; + .yst-progress-bar__progress { + @apply yst-duration-500; + } + } .yst-step { @@ -49,6 +53,5 @@ @apply yst-bg-primary-500 yst-text-white yst-ring-primary-500 yst-transition-none yst-delay-0; } } - } } From 7173c0c930f654518f6a863f2c38b88d3a2624a7 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 15:42:25 +0200 Subject: [PATCH 29/85] fix js docs for stepper --- packages/ui-library/src/elements/stepper/index.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index b0525e3e78e..b952a26c5a5 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -8,14 +8,13 @@ import { ProgressBar } from "../../index"; * Step component. * * @param {string} label The step label. - * @param {number} index The step index. * @param {boolean} isComplete Is the step complete. - * @param {number} currentStep The current step. - * @param {function} addStepRef The function to add the step ref. + * @param {boolean} isActive Is the step + * @param {boolean} isStepComplete Is the step complete. * * @returns {JSX.Element} The step element. */ -const Step = forwardRef( ( { label, isComplete, isActive, isStepComplete }, ref ) => { +const Step = forwardRef( ( { label, isComplete, isActive, isStepComplete }, ref ) => { return (
Date: Tue, 28 Jan 2025 16:39:38 +0200 Subject: [PATCH 30/85] Fix js doc comments --- packages/ui-library/src/elements/stepper/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index b952a26c5a5..4874771b149 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -48,7 +48,7 @@ Step.propTypes = { /** * - * @param {number} currentStep The currrent step. + * @param {number} currentStep The currrent step, not array index based. * @param {boolean} isComplete Is the step complete. * @param {[string]} steps The steps names. * @param {string} [className] Optional extra className. From 4eaa7decfc4691d6f34a4dd2d1debe0e86e7bcc5 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 17:01:58 +0200 Subject: [PATCH 31/85] renaming variables and cleaning Stepper --- packages/ui-library/src/elements/stepper/index.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 4874771b149..9416d74bcf4 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -56,16 +56,16 @@ Step.propTypes = { * @returns {JSX.Element} The Stepper element. */ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" }, ref ) => { - const [ margins, setMargins ] = useState( { - marginLeft: 0, - marginRight: 0, + const [ progressBarPosition, setProgressBarPosition ] = useState( { + left: 0, + right: 0, } ); const stepRef = useRef( [] ); useEffect( () => { - setMargins( { - marginLeft: stepRef.current[ 0 ].offsetWidth / 2, - marginRight: stepRef.current[ steps.length - 1 ].offsetWidth / 2, + setProgressBarPosition( { + left: stepRef.current[ 0 ].offsetWidth / 2, + right: stepRef.current[ steps.length - 1 ].offsetWidth / 2, } ); }, [ stepRef.current, steps.length ] ); @@ -82,7 +82,6 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } label={ step } currentStep={ currentStep } isComplete={ isComplete } - index={ index } isActive={ currentStep === index + 1 } isStepComplete={ currentStep > index + 1 || isComplete } ref={ addStepRef } @@ -90,7 +89,7 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } Date: Tue, 28 Jan 2025 17:03:58 +0200 Subject: [PATCH 32/85] Add comment about the positioning f the progress bar --- packages/ui-library/src/elements/stepper/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 9416d74bcf4..02668c40587 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -63,6 +63,7 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } const stepRef = useRef( [] ); useEffect( () => { + // Get the center of the first and last step to set the progress bar position in the middle. setProgressBarPosition( { left: stepRef.current[ 0 ].offsetWidth / 2, right: stepRef.current[ steps.length - 1 ].offsetWidth / 2, From 1bd29d0591cd295af23467bf145ebcfcbcf98193 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 17:13:03 +0200 Subject: [PATCH 33/85] remove unused prop --- packages/ui-library/src/elements/stepper/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/elements/stepper/index.js index 02668c40587..c7473ed61d0 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/elements/stepper/index.js @@ -81,7 +81,6 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } { steps.map( ( step, index ) => index + 1 || isComplete } From ce56c2507e3ed38c2163b647f553cb1548f393a5 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 20:01:50 +0200 Subject: [PATCH 34/85] implement component Stepper --- .../google-site-kit-connection-widget.js | 11 ++- packages/ui-library/.storybook/style.css | 2 +- .../src/components/stepper/docs/component.md | 1 + .../stepper/docs/index.js | 0 .../{elements => components}/stepper/index.js | 73 ++++++++++--------- .../stepper/stories.js | 27 ++++--- .../stepper/style.css | 0 .../src/elements/stepper/docs/component.md | 1 - packages/ui-library/src/index.js | 2 +- 9 files changed, 68 insertions(+), 49 deletions(-) create mode 100644 packages/ui-library/src/components/stepper/docs/component.md rename packages/ui-library/src/{elements => components}/stepper/docs/index.js (100%) rename packages/ui-library/src/{elements => components}/stepper/index.js (57%) rename packages/ui-library/src/{elements => components}/stepper/stories.js (56%) rename packages/ui-library/src/{elements => components}/stepper/style.css (100%) delete mode 100644 packages/ui-library/src/elements/stepper/docs/component.md diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index acc5ca83682..a1aa0e45cfb 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -99,7 +99,6 @@ export const GoogleSiteKitConnectionWidget = ( { const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ); return - @@ -115,7 +114,15 @@ export const GoogleSiteKitConnectionWidget = ( {
- + + { steps.map( ( label, index ) => ( index + 1 || isComplete } + /> ) ) } +
{ __( "Expand your dashboard with insights from Google!", "wordpress-seo" ) }

{ __( "Bring together powerful tools like Google Analytics and Search Console for a complete overview of your website's performance, all in one seamless dashboard.", "wordpress-seo" ) }

diff --git a/packages/ui-library/.storybook/style.css b/packages/ui-library/.storybook/style.css index 54575456cc4..c07e0cb543a 100644 --- a/packages/ui-library/.storybook/style.css +++ b/packages/ui-library/.storybook/style.css @@ -21,7 +21,6 @@ @import "../src/elements/file-input/style.css"; @import "../src/elements/autocomplete/style.css"; @import "../src/elements/validation/style.css"; -@import "../src/elements/stepper/style.css"; @import "../src/components/autocomplete-field/style.css"; @import "../src/components/card/style.css"; @@ -41,6 +40,7 @@ @import "../src/components/toggle-field/style.css"; @import "../src/components/tooltip-container/style.css"; @import "../src/components/dropdown-menu/style.css"; +@import "../src/components/stepper/style.css"; @tailwind base; @tailwind components; diff --git a/packages/ui-library/src/components/stepper/docs/component.md b/packages/ui-library/src/components/stepper/docs/component.md new file mode 100644 index 00000000000..3abcddd17fc --- /dev/null +++ b/packages/ui-library/src/components/stepper/docs/component.md @@ -0,0 +1 @@ +The stepper element takes takes the number of steps and current step and has Step component to render each step. \ No newline at end of file diff --git a/packages/ui-library/src/elements/stepper/docs/index.js b/packages/ui-library/src/components/stepper/docs/index.js similarity index 100% rename from packages/ui-library/src/elements/stepper/docs/index.js rename to packages/ui-library/src/components/stepper/docs/index.js diff --git a/packages/ui-library/src/elements/stepper/index.js b/packages/ui-library/src/components/stepper/index.js similarity index 57% rename from packages/ui-library/src/elements/stepper/index.js rename to packages/ui-library/src/components/stepper/index.js index c7473ed61d0..a68eb7f3eb0 100644 --- a/packages/ui-library/src/elements/stepper/index.js +++ b/packages/ui-library/src/components/stepper/index.js @@ -1,9 +1,11 @@ import classNames from "classnames"; import PropTypes from "prop-types"; -import React, { forwardRef, useRef, useEffect, useState, useCallback } from "react"; +import React, { forwardRef, useRef, useEffect, useState, useCallback, createContext, useContext } from "react"; import { CheckIcon } from "@heroicons/react/solid"; import { ProgressBar } from "../../index"; +const StepperContext = createContext(); + /** * Step component. * @@ -14,10 +16,11 @@ import { ProgressBar } from "../../index"; * * @returns {JSX.Element} The step element. */ -const Step = forwardRef( ( { label, isComplete, isActive, isStepComplete }, ref ) => { +const Step = ( { label, isComplete, isActive, isStepComplete } ) => { + const addStepRef = useContext( StepperContext ); return (
{ label }
); -} ); +}; Step.displayName = "Step"; Step.propTypes = { @@ -48,14 +51,14 @@ Step.propTypes = { /** * - * @param {number} currentStep The currrent step, not array index based. - * @param {boolean} isComplete Is the step complete. - * @param {[string]} steps The steps names. + * @param {JSX.Node} children Content of the stepper. + * @param {number} numberOfSteps The umber of steps. + * @param {string} [currentStep] The current step. * @param {string} [className] Optional extra className. * * @returns {JSX.Element} The Stepper element. */ -const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" }, ref ) => { +export const Stepper = forwardRef( ( { children, numberOfSteps, currentStep, className = "" }, ref ) => { const [ progressBarPosition, setProgressBarPosition ] = useState( { left: 0, right: 0, @@ -63,51 +66,51 @@ const Stepper = forwardRef( ( { currentStep, isComplete, steps, className = "" } const stepRef = useRef( [] ); useEffect( () => { - // Get the center of the first and last step to set the progress bar position in the middle. - setProgressBarPosition( { - left: stepRef.current[ 0 ].offsetWidth / 2, - right: stepRef.current[ steps.length - 1 ].offsetWidth / 2, - } ); - }, [ stepRef.current, steps.length ] ); + if ( stepRef.current.length > 0 ) { + const firstStepRect = stepRef.current[ 0 ].getBoundingClientRect(); + const lastStepRect = stepRef.current[ numberOfSteps - 1 ].getBoundingClientRect(); + setProgressBarPosition( { + left: firstStepRect.width / 2, + right: lastStepRect.width / 2, + } ); + } + }, [ stepRef.current, numberOfSteps ] ); - if ( ! steps.length ) { + if ( ! numberOfSteps ) { return; } const addStepRef = useCallback( ( el ) => ( stepRef.current.push( el ) ), [ stepRef.current ] ); return ( -
- { steps.map( ( step, index ) => index + 1 || isComplete } - ref={ addStepRef } - /> ) } + +
- -
+ { children } + +
+ ); } ); Stepper.displayName = "Stepper"; Stepper.propTypes = { currentStep: PropTypes.number.isRequired, - isComplete: PropTypes.bool.isRequired, - steps: PropTypes.arrayOf( PropTypes.string ).isRequired, + numberOfSteps: PropTypes.number.isRequired, + children: PropTypes.node.isRequired, className: PropTypes.string, }; Stepper.defaultProps = { className: "", }; -export default Stepper; +Stepper.Step = Step; +Stepper.Step.displayName = "Stepper.Step"; + diff --git a/packages/ui-library/src/elements/stepper/stories.js b/packages/ui-library/src/components/stepper/stories.js similarity index 56% rename from packages/ui-library/src/elements/stepper/stories.js rename to packages/ui-library/src/components/stepper/stories.js index 0e2a65b06e2..bc150922a8e 100644 --- a/packages/ui-library/src/elements/stepper/stories.js +++ b/packages/ui-library/src/components/stepper/stories.js @@ -1,7 +1,7 @@ import React, { useState, useCallback } from "react"; -import Stepper from "."; +import { Stepper } from "."; import { component } from "./docs"; -import Button from "../button/index"; +import { Button } from "../../index"; export const Factory = { parameters: { @@ -10,6 +10,7 @@ export const Factory = { render: ( args ) =>{ const [ currentStep, setCurrentStep ] = useState( 1 ); const [ isComplete, setIsComplete ] = useState( false ); + const steps = [ "INSTALL", "ACTIVATE", "SET UP", "CONNECT" ]; const handleNext = useCallback( () => { setCurrentStep( ( prevStep ) => { @@ -17,7 +18,7 @@ export const Factory = { setIsComplete( false ); return 1; } - if ( prevStep === args.steps.length ) { + if ( prevStep === steps.length ) { setIsComplete( true ); return prevStep; } @@ -26,11 +27,20 @@ export const Factory = { }, [ setIsComplete, setCurrentStep, isComplete ] ); return <> - + + { steps.map( ( step, index ) => index + 1 || isComplete } + /> ) } + + ; @@ -38,10 +48,10 @@ export const Factory = { }; export default { - title: "1) Elements/Stepper", + title: "2) Components/Stepper", component: Stepper, argTypes: { - steps: { control: false }, + className: { control: false }, }, parameters: { docs: { @@ -49,7 +59,6 @@ export default { }, }, args: { - steps: [ "INSTALL", "ACTIVATE", "SET UP", "CONNECT" ], className: "yst-mb-5", }, }; diff --git a/packages/ui-library/src/elements/stepper/style.css b/packages/ui-library/src/components/stepper/style.css similarity index 100% rename from packages/ui-library/src/elements/stepper/style.css rename to packages/ui-library/src/components/stepper/style.css diff --git a/packages/ui-library/src/elements/stepper/docs/component.md b/packages/ui-library/src/elements/stepper/docs/component.md deleted file mode 100644 index 2f30c0b3a2c..00000000000 --- a/packages/ui-library/src/elements/stepper/docs/component.md +++ /dev/null @@ -1 +0,0 @@ -The stepper element takes a list of steps labels, the current step and is the process complete. \ No newline at end of file diff --git a/packages/ui-library/src/index.js b/packages/ui-library/src/index.js index d2ca7a6ccfb..1c4c9c962a8 100644 --- a/packages/ui-library/src/index.js +++ b/packages/ui-library/src/index.js @@ -22,7 +22,6 @@ export { default as Toast, useToastContext } from "./elements/toast"; export { default as Toggle } from "./elements/toggle"; export { default as Tooltip } from "./elements/tooltip"; export { ValidationIcon, ValidationInput, ValidationMessage } from "./elements/validation"; -export { default as Stepper } from "./elements/stepper"; export { default as AutocompleteField } from "./components/autocomplete-field"; export { default as Card } from "./components/card"; @@ -43,6 +42,7 @@ export { default as TextareaField } from "./components/textarea-field"; export { default as ToggleField } from "./components/toggle-field"; export { TooltipContainer, TooltipTrigger, TooltipWithContext, useTooltipContext } from "./components/tooltip-container"; export { DropdownMenu } from "./components/dropdown-menu"; +export { Stepper } from "./components/stepper"; export * from "./hooks"; export * from "./constants"; From 4f201d302271cbe2d4af700f8fbc0353c559b934 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 20:02:17 +0200 Subject: [PATCH 35/85] fixing dropdown menu docs. --- .../ui-library/src/components/dropdown-menu/docs/component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-library/src/components/dropdown-menu/docs/component.md b/packages/ui-library/src/components/dropdown-menu/docs/component.md index 6d28275cac2..8ca8a7f89d6 100644 --- a/packages/ui-library/src/components/dropdown-menu/docs/component.md +++ b/packages/ui-library/src/components/dropdown-menu/docs/component.md @@ -1 +1 @@ -A dropdowm menu with menu item and button item sub components. The menu trigger accepts a node and fallback to three vertical dots if not provided. +A dropdowm menu with menu item and button item sub components. The dropdown menu has the IconTrigger component to render the trigger icon and also Trigger component without ny styling. The dropdown menu has the following sub components: IconTrigger, Trigger, Item, ButtonItem, List. The Items should be the children of List. From ebba34f821c6ccfffdc74ff55083381d26d5de09 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Tue, 28 Jan 2025 20:50:53 +0200 Subject: [PATCH 36/85] fix stepper story Use update args and changed the argTypes --- .../src/components/stepper/stories.js | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/ui-library/src/components/stepper/stories.js b/packages/ui-library/src/components/stepper/stories.js index bc150922a8e..1e9cac14c8f 100644 --- a/packages/ui-library/src/components/stepper/stories.js +++ b/packages/ui-library/src/components/stepper/stories.js @@ -1,4 +1,5 @@ import React, { useState, useCallback } from "react"; +import { useArgs } from "@storybook/preview-api"; import { Stepper } from "."; import { component } from "./docs"; import { Button } from "../../index"; @@ -8,26 +9,24 @@ export const Factory = { controls: { disable: false }, }, render: ( args ) =>{ - const [ currentStep, setCurrentStep ] = useState( 1 ); const [ isComplete, setIsComplete ] = useState( false ); const steps = [ "INSTALL", "ACTIVATE", "SET UP", "CONNECT" ]; + const [ { numberOfSteps, className, currentStep }, updateArgs ] = useArgs(); const handleNext = useCallback( () => { - setCurrentStep( ( prevStep ) => { - if ( isComplete ) { - setIsComplete( false ); - return 1; - } - if ( prevStep === steps.length ) { - setIsComplete( true ); - return prevStep; - } - return prevStep + 1; - } ); - }, [ setIsComplete, setCurrentStep, isComplete ] ); + if ( currentStep < steps.length ) { + setIsComplete( false ); + updateArgs( { currentStep: currentStep + 1 } ); + } else if ( currentStep === steps.length && ! isComplete ) { + setIsComplete( true ); + } else if ( isComplete ) { + setIsComplete( false ); + updateArgs( { currentStep: 1 } ); + } + }, [ setIsComplete, updateArgs, isComplete, currentStep ] ); return <> - + { steps.map( ( step, index ) => Date: Wed, 29 Jan 2025 11:43:35 +0200 Subject: [PATCH 37/85] darken the icon when menu is open --- .../src/components/dropdown-menu/index.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 19a1c04fefd..ff95915ed6f 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -44,11 +44,14 @@ MenuButtonItem.propTypes = { */ const DropdownMenuIconTrigger = ( { className, screenReaderTriggerLabel = "Open menu", Icon = DotsVerticalIcon, ...props } ) => ( - - { screenReaderTriggerLabel } - + { ( { open } ) => <> + + { screenReaderTriggerLabel } + } ); From b44e945c4b85e8fe763a98020865f6f9e481f2c6 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 29 Jan 2025 11:54:10 +0200 Subject: [PATCH 38/85] fix documentation for Dropdown Menu --- .../ui-library/src/components/dropdown-menu/docs/component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-library/src/components/dropdown-menu/docs/component.md b/packages/ui-library/src/components/dropdown-menu/docs/component.md index 8ca8a7f89d6..0f7425beb4d 100644 --- a/packages/ui-library/src/components/dropdown-menu/docs/component.md +++ b/packages/ui-library/src/components/dropdown-menu/docs/component.md @@ -1 +1 @@ -A dropdowm menu with menu item and button item sub components. The dropdown menu has the IconTrigger component to render the trigger icon and also Trigger component without ny styling. The dropdown menu has the following sub components: IconTrigger, Trigger, Item, ButtonItem, List. The Items should be the children of List. +A dropdowm menu with sub components. The dropdown menu has the `DropdownMenu.IconTrigger` component to render the trigger icon and also `DropdownMenu.Trigger` component without ny styling and with the render prop `open`. There are also two item subcomponent that should be rendered under `DropdownMenu.List`, the `DropdownMenu.ButtonItem` which is acts as a `Button` and `DropdownMenu.Item` which accepts `as` prop and without any styling, also accepts `open` render prop. \ No newline at end of file From 1e261763a09fe3efd176a3cd51f2e59dc5584c4f Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 29 Jan 2025 12:11:05 +0200 Subject: [PATCH 39/85] update widget tests --- .../google-site-kit-connection-widget.test.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js b/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js index 219e69a05db..f3d289f3d6c 100644 --- a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js +++ b/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js @@ -9,11 +9,11 @@ describe( "GoogleSiteKitConnectionWidget", () => { const defaultProps = { installUrl: "https://example.com/install", activateUrl: "https://example.com/activate", - setupUrl: "https://example.com/setup", - connected: false, - active: false, - setup: false, - installed: false, + isSetupUrl: "https://example.com/isSetup", + isConnected: false, + isActive: false, + isSetup: false, + isInstalled: false, onRemove: jest.fn(), onRemovePermanently: jest.fn(), }; @@ -24,22 +24,22 @@ describe( "GoogleSiteKitConnectionWidget", () => { } ); it( "renders the widget with activate button", () => { - render( ); + render( ); expect( screen.getByText( "Activate Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with setup button", () => { - render( ); + render( ); expect( screen.getByText( "Set up Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with connect button", () => { - render( ); + render( ); expect( screen.getByText( "Connect Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with dismiss button when connected", () => { - render( ); + render( ); expect( screen.getByText( "Dismiss" ) ).toBeInTheDocument(); } ); From 1fae71a8da43415ebe0a4426be0037ec85a2c889 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 29 Jan 2025 13:09:57 +0200 Subject: [PATCH 40/85] abstract the learn more link --- packages/js/src/dashboard/components/dashboard.js | 5 +++-- .../components/google-site-kit-connection-widget.js | 5 ++--- .../components/google-site-kit-connection-widget.test.js | 5 +---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 378f1b0cde4..303f4dd4ddd 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -4,6 +4,7 @@ import { GoogleSiteKitConnectionWidget } from "./google-site-kit-connection-widg import { get } from "lodash"; import { useCallback } from "@wordpress/element"; import { useToggleState } from "@yoast/ui-library"; +import { useSelect } from "@wordpress/data"; /** * @type {import("../index").ContentType} ContentType @@ -36,7 +37,7 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header featureActive: false, } ); const [ showGoogleSiteKit, , , , setRemoveGoogleSiteKit ] = useToggleState( true ); - + const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); const handleRemovePermanently = useCallback( ()=>{ /* eslint-disable-next-line */ // TODO: Implement the remove permanently functionality. @@ -48,7 +49,7 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header
{ showGoogleSiteKit && googleSiteKitConfiguration.featureActive && } { features.indexables && features.seoAnalysis && ( diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js index a1aa0e45cfb..18b74613826 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-connection-widget.js @@ -3,7 +3,6 @@ import { ReactComponent as YoastConnectSiteKit } from "../../../images/yoast-con import { __ } from "@wordpress/i18n"; import { CheckCircleIcon } from "@heroicons/react/solid"; import { ArrowRightIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; -import { useSelect } from "@wordpress/data"; /** * Get the button and stepper props based on the current state. @@ -80,6 +79,7 @@ const steps = [ * @param {string} setupUrl The URL to setup Site Kit. * @param {function} onRemove The function to call when the widget is removed. * @param {function} onRemovePermanently The function to call when the widget is removed permanently. + * @param {string} learnMorelink The URL to learn more about the feature. * * @returns {JSX.Element} The widget. */ @@ -93,9 +93,8 @@ export const GoogleSiteKitConnectionWidget = ( { isInstalled, onRemove, onRemovePermanently, + learnMorelink, } ) => { - const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); - const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ); return diff --git a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js b/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js index f3d289f3d6c..40c7cf5e29f 100644 --- a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js +++ b/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js @@ -1,10 +1,6 @@ import { render, screen, fireEvent } from "@testing-library/react"; import { GoogleSiteKitConnectionWidget } from "../../../src/dashboard/components/google-site-kit-connection-widget"; -jest.mock( "@wordpress/data", () => ( { - useSelect: jest.fn( () => [] ), -} ) ); - describe( "GoogleSiteKitConnectionWidget", () => { const defaultProps = { installUrl: "https://example.com/install", @@ -16,6 +12,7 @@ describe( "GoogleSiteKitConnectionWidget", () => { isInstalled: false, onRemove: jest.fn(), onRemovePermanently: jest.fn(), + learnMoreLink: "https://example.com/learn-more", }; it( "renders the widget with install button", () => { From 372448ada300ddacc855294b21c8c1f90f60a913 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 29 Jan 2025 17:16:25 +0200 Subject: [PATCH 41/85] renamed to google site kit set up widget --- .../js/src/dashboard/components/dashboard.js | 4 ++-- ...dget.js => google-site-kit-setup-widget.js} | 2 +- ...js => google-site-kit-setup-widget.test.js} | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) rename packages/js/src/dashboard/components/{google-site-kit-connection-widget.js => google-site-kit-setup-widget.js} (99%) rename packages/js/tests/dashboard/components/{google-site-kit-connection-widget.test.js => google-site-kit-setup-widget.test.js} (67%) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 303f4dd4ddd..002ee3efde9 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -1,6 +1,6 @@ import { Scores } from "../scores/components/scores"; import { PageTitle } from "./page-title"; -import { GoogleSiteKitConnectionWidget } from "./google-site-kit-connection-widget"; +import { GoogleSiteKitSetupWidget } from "./google-site-kit-setup-widget"; import { get } from "lodash"; import { useCallback } from "@wordpress/element"; import { useToggleState } from "@yoast/ui-library"; @@ -48,7 +48,7 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header <>
- { showGoogleSiteKit && googleSiteKitConfiguration.featureActive && } diff --git a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js b/packages/js/src/dashboard/components/google-site-kit-setup-widget.js similarity index 99% rename from packages/js/src/dashboard/components/google-site-kit-connection-widget.js rename to packages/js/src/dashboard/components/google-site-kit-setup-widget.js index 18b74613826..a361a848450 100644 --- a/packages/js/src/dashboard/components/google-site-kit-connection-widget.js +++ b/packages/js/src/dashboard/components/google-site-kit-setup-widget.js @@ -83,7 +83,7 @@ const steps = [ * * @returns {JSX.Element} The widget. */ -export const GoogleSiteKitConnectionWidget = ( { +export const GoogleSiteKitSetupWidget = ( { installUrl, activateUrl, setupUrl, diff --git a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js b/packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js similarity index 67% rename from packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js rename to packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js index 40c7cf5e29f..0cf30ce142c 100644 --- a/packages/js/tests/dashboard/components/google-site-kit-connection-widget.test.js +++ b/packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js @@ -1,7 +1,7 @@ import { render, screen, fireEvent } from "@testing-library/react"; -import { GoogleSiteKitConnectionWidget } from "../../../src/dashboard/components/google-site-kit-connection-widget"; +import { GoogleSiteKitSetupWidget } from "../../../src/dashboard/components/google-site-kit-setup-widget"; -describe( "GoogleSiteKitConnectionWidget", () => { +describe( "GoogleSiteKitSetupWidget", () => { const defaultProps = { installUrl: "https://example.com/install", activateUrl: "https://example.com/activate", @@ -16,39 +16,39 @@ describe( "GoogleSiteKitConnectionWidget", () => { }; it( "renders the widget with install button", () => { - render( ); + render( ); expect( screen.getByText( "Install Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with activate button", () => { - render( ); + render( ); expect( screen.getByText( "Activate Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with setup button", () => { - render( ); + render( ); expect( screen.getByText( "Set up Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with connect button", () => { - render( ); + render( ); expect( screen.getByText( "Connect Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with dismiss button when connected", () => { - render( ); + render( ); expect( screen.getByText( "Dismiss" ) ).toBeInTheDocument(); } ); it( "opens the menu and calls onRemove when 'Remove until next visit' is clicked", () => { - render( ); + render( ); fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); fireEvent.click( screen.getByText( "Remove until next visit" ) ); expect( defaultProps.onRemove ).toHaveBeenCalled(); } ); it( "opens the menu and calls onRemovePermanently when 'Remove permanently' is clicked", () => { - render( ); + render( ); fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); fireEvent.click( screen.getByText( "Remove permanently" ) ); expect( defaultProps.onRemovePermanently ).toHaveBeenCalled(); From 608e13129ccdc87d923d7bdfa026c2abccef1d3f Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Thu, 30 Jan 2025 11:00:51 +0200 Subject: [PATCH 42/85] rename to site kit setup widget --- .../js/src/dashboard/components/dashboard.js | 4 ++-- ...etup-widget.js => site-kit-setup-widget.js} | 2 +- .../google-site-kit-setup-widget.test.js | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) rename packages/js/src/dashboard/components/{google-site-kit-setup-widget.js => site-kit-setup-widget.js} (99%) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 002ee3efde9..ef60a2b7a94 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -1,6 +1,6 @@ import { Scores } from "../scores/components/scores"; import { PageTitle } from "./page-title"; -import { GoogleSiteKitSetupWidget } from "./google-site-kit-setup-widget"; +import { SiteKitSetupWidget } from "./site-kit-setup-widget"; import { get } from "lodash"; import { useCallback } from "@wordpress/element"; import { useToggleState } from "@yoast/ui-library"; @@ -48,7 +48,7 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header <>
- { showGoogleSiteKit && googleSiteKitConfiguration.featureActive && } diff --git a/packages/js/src/dashboard/components/google-site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js similarity index 99% rename from packages/js/src/dashboard/components/google-site-kit-setup-widget.js rename to packages/js/src/dashboard/components/site-kit-setup-widget.js index a361a848450..42b808c1a75 100644 --- a/packages/js/src/dashboard/components/google-site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -83,7 +83,7 @@ const steps = [ * * @returns {JSX.Element} The widget. */ -export const GoogleSiteKitSetupWidget = ( { +export const SiteKitSetupWidget = ( { installUrl, activateUrl, setupUrl, diff --git a/packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js b/packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js index 0cf30ce142c..cabe7516828 100644 --- a/packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js +++ b/packages/js/tests/dashboard/components/google-site-kit-setup-widget.test.js @@ -1,7 +1,7 @@ import { render, screen, fireEvent } from "@testing-library/react"; -import { GoogleSiteKitSetupWidget } from "../../../src/dashboard/components/google-site-kit-setup-widget"; +import { SiteKitSetupWidget } from "../../../src/dashboard/components/site-kit-setup-widget"; -describe( "GoogleSiteKitSetupWidget", () => { +describe( "SiteKitSetupWidget", () => { const defaultProps = { installUrl: "https://example.com/install", activateUrl: "https://example.com/activate", @@ -16,39 +16,39 @@ describe( "GoogleSiteKitSetupWidget", () => { }; it( "renders the widget with install button", () => { - render( ); + render( ); expect( screen.getByText( "Install Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with activate button", () => { - render( ); + render( ); expect( screen.getByText( "Activate Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with setup button", () => { - render( ); + render( ); expect( screen.getByText( "Set up Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with connect button", () => { - render( ); + render( ); expect( screen.getByText( "Connect Site Kit by Google" ) ).toBeInTheDocument(); } ); it( "renders the widget with dismiss button when connected", () => { - render( ); + render( ); expect( screen.getByText( "Dismiss" ) ).toBeInTheDocument(); } ); it( "opens the menu and calls onRemove when 'Remove until next visit' is clicked", () => { - render( ); + render( ); fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); fireEvent.click( screen.getByText( "Remove until next visit" ) ); expect( defaultProps.onRemove ).toHaveBeenCalled(); } ); it( "opens the menu and calls onRemovePermanently when 'Remove permanently' is clicked", () => { - render( ); + render( ); fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); fireEvent.click( screen.getByText( "Remove permanently" ) ); expect( defaultProps.onRemovePermanently ).toHaveBeenCalled(); From ccf0c7f6ecf882183017ba7cd8294174a6bbbd94 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Fri, 31 Jan 2025 16:28:20 +0200 Subject: [PATCH 43/85] fix renaming and implement site kit configuration data --- .../js/src/dashboard/components/dashboard.js | 10 ++-- .../components/site-kit-setup-widget.js | 12 ++--- .../google-site-kit-integration.js | 14 +++--- .../recommended-integrations.js | 10 ++-- .../configuration/dashboard-configuration.php | 47 ++++++------------- .../Integrations_Page_Integration_Test.php | 16 +++---- 6 files changed, 45 insertions(+), 64 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index ef60a2b7a94..ea715fc0075 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -26,15 +26,15 @@ import { useSelect } from "@wordpress/data"; // The complexity is cause by the google site kit feature flag which is temporary. // eslint-disable-next-line complexity export const Dashboard = ( { contentTypes, userName, features, endpoints, headers, links } ) => { - const googleSiteKitConfiguration = get( window, "wpseoScriptData.dashboard.googleSiteKit", { + const siteKitConfiguration = get( window, "wpseoScriptData.dashboard.siteKitConfiguration", { isInstalled: false, isActive: false, - isSetup: false, + isSetupCompleted: false, isConnected: false, installUrl: "", activateUrl: "", setupUrl: "", - featureActive: false, + isFeatureEnabled: false, } ); const [ showGoogleSiteKit, , , , setRemoveGoogleSiteKit ] = useToggleState( true ); const learnMorelink = useSelect( select => select( "@yoast/general" ).selectLink( "https://yoa.st/google-site-kit-learn-more" ), [] ); @@ -48,8 +48,8 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header <>
- { showGoogleSiteKit && googleSiteKitConfiguration.featureActive && } { features.indexables && features.seoAnalysis && ( diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index 42b808c1a75..f6aabfb0419 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -9,7 +9,7 @@ import { ArrowRightIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; * * @param {boolean} isInstalled Whether the plugin is isInstalled. * @param {boolean} isActive Whether the feature is active. - * @param {boolean} isSetup Whether the setup is complete. + * @param {boolean} isSetupCompleted Whether the setup is complete. * @param {boolean} isConnected Whether the connection is active. * @param {string} installUrl The URL to install Site Kit. * @param {string} activateUrl The URL to activate Site Kit. @@ -17,7 +17,7 @@ import { ArrowRightIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; * * @returns {Object} The button and stepper props. */ -const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ) => { +const getButtonAndStepperProps = ( isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, setupUrl ) => { let buttonProps; let currentStep; let isComplete = false; @@ -39,7 +39,7 @@ const getButtonAndStepperProps = ( isInstalled, isActive, isSetup, isConnected, href: activateUrl, }; break; - case ( ! isSetup ): + case ( ! isSetupCompleted ): currentStep = 3; buttonProps = { children: __( "Set up Site Kit by Google", "wordpress-seo" ), @@ -72,7 +72,7 @@ const steps = [ * * @param {boolean} isInstalled Whether the plugin is installed. * @param {boolean} isActive Whether the feature is active. - * @param {boolean} isSetup Whether the setup is complete. + * @param {boolean} isSetupCompleted Whether the setup is complete. * @param {boolean} isConnected Whether the connection is active. * @param {string} installUrl The URL to install Site Kit. * @param {string} activateUrl The URL to activate Site Kit. @@ -89,14 +89,14 @@ export const SiteKitSetupWidget = ( { setupUrl, isConnected, isActive, - isSetup, + isSetupCompleted, isInstalled, onRemove, onRemovePermanently, learnMorelink, } ) => { const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( - isInstalled, isActive, isSetup, isConnected, installUrl, activateUrl, setupUrl ); + isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, setupUrl ); return diff --git a/packages/js/src/integrations-page/google-site-kit-integration.js b/packages/js/src/integrations-page/google-site-kit-integration.js index 968587c748d..00f8c2b0f3f 100644 --- a/packages/js/src/integrations-page/google-site-kit-integration.js +++ b/packages/js/src/integrations-page/google-site-kit-integration.js @@ -49,7 +49,7 @@ const SuccessfullyConnected = () => { * The Site Kit integration component. * * @param {boolean} isActive Whether the integration is active. - * @param {boolean} afterSetup Whether the integration has been set up. + * @param {boolean} isSetupCompleted Whether the integration has been set up. * @param {boolean} isInstalled Whether the integration is installed. * @param {boolean} isConnected Whether the integration is connected. * @param {string} installUrl The installation url. @@ -58,7 +58,7 @@ const SuccessfullyConnected = () => { * * @returns {WPElement} The Site Kit integration component. */ -export const GoogleSiteKitIntegration = ( { isActive, afterSetup, isInstalled, isConnected, installUrl, activateUrl, setupUrl } ) => { +export const GoogleSiteKitIntegration = ( { isActive, isSetupCompleted, isInstalled, isConnected, installUrl, activateUrl, setupUrl } ) => { const [ isModalOpen, toggleModal ] = useToggleState( false ); const getButtonProps = useCallback( () => { @@ -76,7 +76,7 @@ export const GoogleSiteKitIntegration = ( { isActive, afterSetup, isInstalled, i href: activateUrl, }; } - if ( ! afterSetup ) { + if ( ! isSetupCompleted ) { return { children: __( "Set up Site Kit by Google", "wordpress-seo" ), as: "a", @@ -96,10 +96,10 @@ export const GoogleSiteKitIntegration = ( { isActive, afterSetup, isInstalled, i as: "button", variant: "secondary", }; - }, [ isInstalled, isActive, afterSetup, isConnected, installUrl, activateUrl, toggleModal ] ); + }, [ isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, toggleModal ] ); - const successfullyConnected = isInstalled && isActive && afterSetup && isConnected; + const successfullyConnected = isInstalled && isActive && isSetupCompleted && isConnected; return ( <> { successfullyConnected && } - : }
From 5c310753014a8cf1ffb559986ce6890812f53754 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 14:38:14 +0200 Subject: [PATCH 54/85] adds missing class name docs --- packages/ui-library/src/components/dropdown-menu/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index e77dcff3532..59b65da8775 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -65,8 +65,9 @@ DropdownMenuIconTrigger.propTypes = { * Dropdown menu list. * * @param {JSX.node} children Content of the menu. + * @param {string} [className] CSS class. * - * @returns {JSX.Element} Menu component. + * @returns {JSX.Element} Menu list component. */ const DropdownMenuList = ( { children, className } ) => { return ( From 3d61b5a5690f32a3211959ab742ceb78f7531342 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 14:57:58 +0200 Subject: [PATCH 55/85] fix tests for the menu item buttons --- .../dashboard/components/site-kit-setup-widget.test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/js/tests/dashboard/components/site-kit-setup-widget.test.js b/packages/js/tests/dashboard/components/site-kit-setup-widget.test.js index 46ea7f8796f..a4f16577837 100644 --- a/packages/js/tests/dashboard/components/site-kit-setup-widget.test.js +++ b/packages/js/tests/dashboard/components/site-kit-setup-widget.test.js @@ -43,14 +43,16 @@ describe( "SiteKitSetupWidget", () => { it( "opens the menu and calls onRemove when 'Remove until next visit' is clicked", () => { render( ); fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); - fireEvent.click( screen.getByText( "Remove until next visit" ) ); + const removeButton = screen.getByRole( "menuitem", { name: /Remove until next visit/i, type: "button" } ); + fireEvent.click( removeButton ); expect( defaultProps.onRemove ).toHaveBeenCalled(); } ); it( "opens the menu and calls onRemovePermanently when 'Remove permanently' is clicked", () => { render( ); fireEvent.click( screen.getByRole( "button", { name: /open menu/i } ) ); - fireEvent.click( screen.getByText( "Remove permanently" ) ); + const removeButton = screen.getByRole( "menuitem", { name: /Remove permanently/i, type: "button" } ); + fireEvent.click( removeButton ); expect( defaultProps.onRemovePermanently ).toHaveBeenCalled(); } ); } ); From 69a00a73f66e0f051be4694ad560c5dbf3053794 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 14:58:19 +0200 Subject: [PATCH 56/85] fix menu return docs --- packages/ui-library/src/components/dropdown-menu/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 59b65da8775..992c67ef264 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -23,7 +23,6 @@ const MenuButtonItem = ( { children, className, ...props } ) => { className ) } > { children } - ); }; @@ -97,7 +96,7 @@ DropdownMenuList.propTypes = { * @param {JSX.node} children Content of the menu. * @param {object} props The menu props. * - * @returns {JSX.Element} Menu component. + * @returns {JSX.Element} Dropdown menu component. */ export const DropdownMenu = ( { children, ...props } ) => { return ( From ad43745920ffd4417e02b26952f242b2bbf2259b Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 15:03:58 +0200 Subject: [PATCH 57/85] format props for readability --- packages/js/src/dashboard/components/dashboard.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index ea715fc0075..4ac86adc195 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -49,8 +49,10 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header
{ showGoogleSiteKit && siteKitConfiguration.isFeatureEnabled && } { features.indexables && features.seoAnalysis && ( From 5e9ead646c981d979d15ede107f84a99c365840d Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 15:24:45 +0200 Subject: [PATCH 58/85] fix screen reader text --- packages/js/src/dashboard/components/site-kit-setup-widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index 417fd896917..5ea25cc591f 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -99,7 +99,7 @@ export const SiteKitSetupWidget = ( { isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, setupUrl ); return - + From cca64f0eb069b57b9d08bd3f11008fe3e699a73a Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 15:32:36 +0200 Subject: [PATCH 59/85] fix screen reader text and css --- packages/js/src/dashboard/components/site-kit-setup-widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index 5ea25cc591f..04c601e499a 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -99,8 +99,8 @@ export const SiteKitSetupWidget = ( { isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, setupUrl ); return - - + + { __( "Remove until next visit", "wordpress-seo" ) } From 650c8dc56f5431cc175e163c17052ef42e6a0d63 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 15:40:27 +0200 Subject: [PATCH 60/85] adds gap between buttons --- packages/js/src/dashboard/components/site-kit-setup-widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index 04c601e499a..d2038c6234b 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -137,7 +137,7 @@ export const SiteKitSetupWidget = ( { { __( "Key performance metrics to fine-tune your website and optimize like a pro.", "wordpress-seo" ) } -
+
From a532bca8927f3977fe801c4587c5d6b37ccfe1c9 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:10:12 +0200 Subject: [PATCH 61/85] fix dropdown menu story docs --- .../src/components/dropdown-menu/docs/component.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ui-library/src/components/dropdown-menu/docs/component.md b/packages/ui-library/src/components/dropdown-menu/docs/component.md index 0f7425beb4d..b62385154e7 100644 --- a/packages/ui-library/src/components/dropdown-menu/docs/component.md +++ b/packages/ui-library/src/components/dropdown-menu/docs/component.md @@ -1 +1,5 @@ -A dropdowm menu with sub components. The dropdown menu has the `DropdownMenu.IconTrigger` component to render the trigger icon and also `DropdownMenu.Trigger` component without ny styling and with the render prop `open`. There are also two item subcomponent that should be rendered under `DropdownMenu.List`, the `DropdownMenu.ButtonItem` which is acts as a `Button` and `DropdownMenu.Item` which accepts `as` prop and without any styling, also accepts `open` render prop. \ No newline at end of file +A dropdowm menu with sub components. The childrem on the dropdown menu should be the list of items `DropdownMenu.List` and the trigger `DropdownMenu.Trigger` or `DropdownMenu.IconTrigger`. The `DropdownMenu.List` should have the `DropdownMenu.Item` or `DropdownMenu.ButtonItem` as children. + +The `DropdownMenu.IconTrigger` component renders the trigger as an icon. +The `DropdownMenu.Trigger` component is the trigger without any styling and with the render prop `open`. +The `DropdownMenu.ButtonItem` component acts as a `Button`, while `DropdownMenu.Item` accepts `as` prop, without any styling, and render prop `open`. \ No newline at end of file From 1a9e5ac5813068172f156a65a4f83d423161fb48 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:11:06 +0200 Subject: [PATCH 62/85] use gap instead of margin --- .../js/src/dashboard/components/site-kit-setup-widget.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index d2038c6234b..eff307a660e 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -141,8 +141,9 @@ export const SiteKitSetupWidget = ( { - : }
From 1acc88ba652a65187ea98ed461478f45761fa02e Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:14:46 +0200 Subject: [PATCH 63/85] fix docs for dropdown storybook --- .../ui-library/src/components/dropdown-menu/docs/component.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/ui-library/src/components/dropdown-menu/docs/component.md b/packages/ui-library/src/components/dropdown-menu/docs/component.md index b62385154e7..eb6eeabcddb 100644 --- a/packages/ui-library/src/components/dropdown-menu/docs/component.md +++ b/packages/ui-library/src/components/dropdown-menu/docs/component.md @@ -1,3 +1,5 @@ +The dropdown menu component allows you to create a dropdown menu with a trigger and a list of items. The dropdown menu can be triggered by a button or an icon. The dropdown menu can be opened by clicking on the trigger. The dropdown menu can be closed by clicking outside the dropdown menu or by clicking on the trigger again. + A dropdowm menu with sub components. The childrem on the dropdown menu should be the list of items `DropdownMenu.List` and the trigger `DropdownMenu.Trigger` or `DropdownMenu.IconTrigger`. The `DropdownMenu.List` should have the `DropdownMenu.Item` or `DropdownMenu.ButtonItem` as children. The `DropdownMenu.IconTrigger` component renders the trigger as an icon. From 5368c5e293e8997f6baa4a2c659231953ee92ab1 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:20:10 +0200 Subject: [PATCH 64/85] adds props spread to list --- packages/ui-library/src/components/dropdown-menu/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 992c67ef264..60226e78064 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -42,7 +42,7 @@ MenuButtonItem.propTypes = { * @returns {JSX.Element} Menu trigger component. */ const DropdownMenuIconTrigger = ( { className, screenReaderTriggerLabel = "Open menu", Icon = DotsVerticalIcon, ...props } ) => ( - + { ( { open } ) => <> { +const DropdownMenuList = ( { children, className, ...props } ) => { return ( { leaveFrom="yst-transform yst-opacity-100 yst-scale-100" leaveTo="yst-transform yst-opacity-0 yst-scale-95" > - + { children } From e22a6e4eb9b447e15d4c664c24d608492a0d02b8 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:28:55 +0200 Subject: [PATCH 65/85] Added screen reader prop as required --- .../src/components/dropdown-menu/index.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 60226e78064..56e0e11aa77 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -13,7 +13,7 @@ import { Button } from "../../index"; * * @returns {JSX.Element} Button component. */ -const MenuButtonItem = ( { children, className, ...props } ) => { +const ButtonItem = ( { children, className, ...props } ) => { return ( { ); }; -MenuButtonItem.propTypes = { +ButtonItem.propTypes = { children: PropTypes.node.isRequired, className: PropTypes.string, }; @@ -36,12 +36,12 @@ MenuButtonItem.propTypes = { * Dropdown menu icon trigger. * * @param {string} [className] CSS class. - * @param {string} [screenReaderTriggerLabel] Screen reader label. + * @param {string} [screenReaderTriggerLabel] Screen reader label for the menu trigger. * @param {JSX.node} [Icon] Icon component. * * @returns {JSX.Element} Menu trigger component. */ -const DropdownMenuIconTrigger = ( { className, screenReaderTriggerLabel = "Open menu", Icon = DotsVerticalIcon, ...props } ) => ( +const IconTrigger = ( { className, screenReaderTriggerLabel, Icon = DotsVerticalIcon, ...props } ) => ( { ( { open } ) => <> Date: Wed, 5 Feb 2025 16:35:07 +0200 Subject: [PATCH 66/85] fix doc for button item fix docs --- packages/ui-library/src/components/dropdown-menu/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 56e0e11aa77..f3136b1a2fe 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -6,12 +6,12 @@ import { Menu, Transition } from "@headlessui/react"; import { Button } from "../../index"; /** - * The button Item for the dropdown menu. + * The item for the dropdown menu that renders as ui library Button with tertiary variant. * * @param {JSX.node} children Content of the button. * @param {string} [className] CSS class. * - * @returns {JSX.Element} Button component. + * @returns {JSX.Element} Button item component. */ const ButtonItem = ( { children, className, ...props } ) => { return ( From c183c9d5c9be0d3228a539352979f674b8cfec30 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:52:10 +0200 Subject: [PATCH 67/85] moved styling outside the ui library --- .../src/components/dropdown-menu/index.js | 2 +- .../src/components/dropdown-menu/stories.js | 4 ++-- .../src/components/dropdown-menu/style.css | 13 ------------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index f3136b1a2fe..4f2940262b7 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -19,7 +19,7 @@ const ButtonItem = ( { children, className, ...props } ) => { as={ Button } variant="tertiary" { ...props } - className={ classNames( "yst-dropdown-menu__item yst-dropdown-menu__item--button", + className={ classNames( "yst-dropdown-menu__item--button", className ) } > { children } diff --git a/packages/ui-library/src/components/dropdown-menu/stories.js b/packages/ui-library/src/components/dropdown-menu/stories.js index 33c74fdf91b..7adf2faf2a4 100644 --- a/packages/ui-library/src/components/dropdown-menu/stories.js +++ b/packages/ui-library/src/components/dropdown-menu/stories.js @@ -13,11 +13,11 @@ export const Factory = { Item - + Button Item - + Button Item diff --git a/packages/ui-library/src/components/dropdown-menu/style.css b/packages/ui-library/src/components/dropdown-menu/style.css index 97a38fcf846..99a27163553 100644 --- a/packages/ui-library/src/components/dropdown-menu/style.css +++ b/packages/ui-library/src/components/dropdown-menu/style.css @@ -2,7 +2,6 @@ .yst-root { .yst-dropdown-menu__icon-trigger { @apply - yst-p-0 yst-text-slate-400 yst-rounded-full focus:yst-text-slate-600 @@ -12,20 +11,8 @@ focus:yst-outline-primary-500; } - .yst-dropdown-menu__item { - @apply - yst-border-b - yst-border-slate-200 - last:yst-border-0 - yst-text-slate-600; - } - .yst-dropdown-menu__item--button { @apply - yst-flex - yst-py-2 - yst-justify-start - yst-gap-2 yst-px-4 yst-items-center yst-w-full yst-ring-0 From 1cf12739356b0c665232594a9c13880dd83ece7e Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:52:36 +0200 Subject: [PATCH 68/85] add the styling from the ui library --- .../src/dashboard/components/site-kit-setup-widget.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index eff307a660e..76f8a3d3636 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -101,11 +101,17 @@ export const SiteKitSetupWidget = ( { - + { __( "Remove until next visit", "wordpress-seo" ) } - + { __( "Remove permanently", "wordpress-seo" ) } From 017ce91deb39c542bb8438dd177d59e0f360b4a3 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 16:56:11 +0200 Subject: [PATCH 69/85] move width outside ui library for flexability --- packages/js/src/dashboard/components/site-kit-setup-widget.js | 2 +- packages/ui-library/src/components/dropdown-menu/style.css | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index 76f8a3d3636..7bfa0aa9e1c 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -100,7 +100,7 @@ export const SiteKitSetupWidget = ( { return - + Date: Wed, 5 Feb 2025 17:08:17 +0200 Subject: [PATCH 70/85] Adds default to stepper context and expose it --- packages/ui-library/src/components/stepper/index.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/ui-library/src/components/stepper/index.js b/packages/ui-library/src/components/stepper/index.js index a68eb7f3eb0..089d5646c39 100644 --- a/packages/ui-library/src/components/stepper/index.js +++ b/packages/ui-library/src/components/stepper/index.js @@ -3,8 +3,14 @@ import PropTypes from "prop-types"; import React, { forwardRef, useRef, useEffect, useState, useCallback, createContext, useContext } from "react"; import { CheckIcon } from "@heroicons/react/solid"; import { ProgressBar } from "../../index"; +import { noop } from "lodash"; -const StepperContext = createContext(); +/** + * Context for the stepper. Used to add a reference to the step. + */ +const StepperContext = createContext( { + addStepRef: noop, +} ); /** * Step component. @@ -112,5 +118,6 @@ Stepper.defaultProps = { }; Stepper.Step = Step; +Stepper.Context = StepperContext; Stepper.Step.displayName = "Stepper.Step"; From 20e12dcd3259966365ff97e5c06f088be7e9dcd1 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 17:18:36 +0200 Subject: [PATCH 71/85] fix step props --- .../js/src/dashboard/components/site-kit-setup-widget.js | 3 +-- packages/ui-library/src/components/stepper/index.js | 8 +++----- packages/ui-library/src/components/stepper/stories.js | 3 +-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index 7bfa0aa9e1c..f47b9e75786 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -124,8 +124,7 @@ export const SiteKitSetupWidget = ( { key={ label } label={ label } isActive={ currentStep === index + 1 } - isComplete={ isComplete } - isStepComplete={ currentStep > index + 1 || isComplete } + isComplete={ currentStep > index + 1 || isComplete } /> ) ) }
diff --git a/packages/ui-library/src/components/stepper/index.js b/packages/ui-library/src/components/stepper/index.js index 089d5646c39..18a9d0f7e85 100644 --- a/packages/ui-library/src/components/stepper/index.js +++ b/packages/ui-library/src/components/stepper/index.js @@ -18,21 +18,20 @@ const StepperContext = createContext( { * @param {string} label The step label. * @param {boolean} isComplete Is the step complete. * @param {boolean} isActive Is the step - * @param {boolean} isStepComplete Is the step complete. * * @returns {JSX.Element} The step element. */ -const Step = ( { label, isComplete, isActive, isStepComplete } ) => { +const Step = ( { label, isComplete, isActive } ) => { const addStepRef = useContext( StepperContext ); return (
- { isStepComplete && } @@ -52,7 +51,6 @@ Step.propTypes = { label: PropTypes.string.isRequired, isActive: PropTypes.bool.isRequired, isComplete: PropTypes.bool.isRequired, - isStepComplete: PropTypes.bool.isRequired, }; /** diff --git a/packages/ui-library/src/components/stepper/stories.js b/packages/ui-library/src/components/stepper/stories.js index 1e9cac14c8f..01ab9ded9d7 100644 --- a/packages/ui-library/src/components/stepper/stories.js +++ b/packages/ui-library/src/components/stepper/stories.js @@ -30,9 +30,8 @@ export const Factory = { { steps.map( ( step, index ) => index + 1 || isComplete } isActive={ currentStep === index + 1 } - isStepComplete={ currentStep > index + 1 || isComplete } /> ) } From c4abeb3d30db3556129c86027e3f149728ba537a Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 17:21:55 +0200 Subject: [PATCH 72/85] fix context --- packages/ui-library/src/components/stepper/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui-library/src/components/stepper/index.js b/packages/ui-library/src/components/stepper/index.js index 18a9d0f7e85..7a5fd55ca3c 100644 --- a/packages/ui-library/src/components/stepper/index.js +++ b/packages/ui-library/src/components/stepper/index.js @@ -22,7 +22,7 @@ const StepperContext = createContext( { * @returns {JSX.Element} The step element. */ const Step = ( { label, isComplete, isActive } ) => { - const addStepRef = useContext( StepperContext ); + const { addStepRef } = useContext( StepperContext ); return (
( stepRef.current.push( el ) ), [ stepRef.current ] ); return ( - +
{ children } From 2c8ea3632cbb70b22e04a405e2ed853dc460be38 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Wed, 5 Feb 2025 17:32:41 +0200 Subject: [PATCH 73/85] remove number of steps --- .../dashboard/components/site-kit-setup-widget.js | 2 +- .../ui-library/src/components/stepper/index.js | 14 ++++---------- .../ui-library/src/components/stepper/stories.js | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index f47b9e75786..b7dc072140f 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -119,7 +119,7 @@ export const SiteKitSetupWidget = ( {
- + { steps.map( ( label, index ) => ( { +export const Stepper = forwardRef( ( { children, currentStep, className = "" }, ref ) => { const [ progressBarPosition, setProgressBarPosition ] = useState( { left: 0, right: 0, @@ -72,17 +71,13 @@ export const Stepper = forwardRef( ( { children, numberOfSteps, currentStep, cla useEffect( () => { if ( stepRef.current.length > 0 ) { const firstStepRect = stepRef.current[ 0 ].getBoundingClientRect(); - const lastStepRect = stepRef.current[ numberOfSteps - 1 ].getBoundingClientRect(); + const lastStepRect = stepRef.current[ stepRef.current.length - 1 ].getBoundingClientRect(); setProgressBarPosition( { left: firstStepRect.width / 2, right: lastStepRect.width / 2, } ); } - }, [ stepRef.current, numberOfSteps ] ); - - if ( ! numberOfSteps ) { - return; - } + }, [ stepRef.current ] ); const addStepRef = useCallback( ( el ) => ( stepRef.current.push( el ) ), [ stepRef.current ] ); @@ -96,7 +91,7 @@ export const Stepper = forwardRef( ( { children, numberOfSteps, currentStep, cla className="yst-absolute yst-top-3 yst-w-auto yst-h-0.5" style={ progressBarPosition } min={ 0 } - max={ numberOfSteps - 1 } + max={ stepRef.current.length - 1 } progress={ currentStep - 1 } />
@@ -107,7 +102,6 @@ export const Stepper = forwardRef( ( { children, numberOfSteps, currentStep, cla Stepper.displayName = "Stepper"; Stepper.propTypes = { currentStep: PropTypes.number.isRequired, - numberOfSteps: PropTypes.number.isRequired, children: PropTypes.node.isRequired, className: PropTypes.string, }; diff --git a/packages/ui-library/src/components/stepper/stories.js b/packages/ui-library/src/components/stepper/stories.js index 01ab9ded9d7..9acfcf070f9 100644 --- a/packages/ui-library/src/components/stepper/stories.js +++ b/packages/ui-library/src/components/stepper/stories.js @@ -11,7 +11,7 @@ export const Factory = { render: ( args ) =>{ const [ isComplete, setIsComplete ] = useState( false ); const steps = [ "INSTALL", "ACTIVATE", "SET UP", "CONNECT" ]; - const [ { numberOfSteps, className, currentStep }, updateArgs ] = useArgs(); + const [ { className, currentStep }, updateArgs ] = useArgs(); const handleNext = useCallback( () => { if ( currentStep < steps.length ) { @@ -26,7 +26,7 @@ export const Factory = { }, [ setIsComplete, updateArgs, isComplete, currentStep ] ); return <> - + { steps.map( ( step, index ) => Date: Wed, 5 Feb 2025 17:39:56 +0200 Subject: [PATCH 74/85] fix docs for stepper --- packages/ui-library/src/components/stepper/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-library/src/components/stepper/index.js b/packages/ui-library/src/components/stepper/index.js index c8d63fb89e8..c868c8b7bf2 100644 --- a/packages/ui-library/src/components/stepper/index.js +++ b/packages/ui-library/src/components/stepper/index.js @@ -56,7 +56,7 @@ Step.propTypes = { /** * * @param {JSX.Node} children Content of the stepper. - * @param {string} [currentStep] The current step. + * @param {number} [currentStep] The current step. * @param {string} [className] Optional extra className. * * @returns {JSX.Element} The Stepper element. From 3e7b387a30b78ed0b3f41c073a514848b28cc6b5 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Thu, 6 Feb 2025 12:08:23 +0200 Subject: [PATCH 75/85] fix stepper current index to start from 0 --- .../ui-library/src/components/stepper/index.js | 8 ++++---- .../src/components/stepper/stories.js | 18 ++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/ui-library/src/components/stepper/index.js b/packages/ui-library/src/components/stepper/index.js index c868c8b7bf2..635bef3ec8d 100644 --- a/packages/ui-library/src/components/stepper/index.js +++ b/packages/ui-library/src/components/stepper/index.js @@ -1,6 +1,6 @@ import classNames from "classnames"; import PropTypes from "prop-types"; -import React, { forwardRef, useRef, useEffect, useState, useCallback, createContext, useContext } from "react"; +import React, { forwardRef, useRef, useState, useCallback, createContext, useContext, useLayoutEffect } from "react"; import { CheckIcon } from "@heroicons/react/solid"; import { ProgressBar } from "../../index"; import { noop } from "lodash"; @@ -56,7 +56,7 @@ Step.propTypes = { /** * * @param {JSX.Node} children Content of the stepper. - * @param {number} [currentStep] The current step. + * @param {number} [currentStep] The current step, starts from 0. * @param {string} [className] Optional extra className. * * @returns {JSX.Element} The Stepper element. @@ -68,7 +68,7 @@ export const Stepper = forwardRef( ( { children, currentStep, className = "" }, } ); const stepRef = useRef( [] ); - useEffect( () => { + useLayoutEffect( () => { if ( stepRef.current.length > 0 ) { const firstStepRect = stepRef.current[ 0 ].getBoundingClientRect(); const lastStepRect = stepRef.current[ stepRef.current.length - 1 ].getBoundingClientRect(); @@ -92,7 +92,7 @@ export const Stepper = forwardRef( ( { children, currentStep, className = "" }, style={ progressBarPosition } min={ 0 } max={ stepRef.current.length - 1 } - progress={ currentStep - 1 } + progress={ currentStep } />
diff --git a/packages/ui-library/src/components/stepper/stories.js b/packages/ui-library/src/components/stepper/stories.js index 9acfcf070f9..4f528ae3851 100644 --- a/packages/ui-library/src/components/stepper/stories.js +++ b/packages/ui-library/src/components/stepper/stories.js @@ -14,14 +14,14 @@ export const Factory = { const [ { className, currentStep }, updateArgs ] = useArgs(); const handleNext = useCallback( () => { - if ( currentStep < steps.length ) { + if ( currentStep < steps.length - 1 ) { setIsComplete( false ); updateArgs( { currentStep: currentStep + 1 } ); - } else if ( currentStep === steps.length && ! isComplete ) { + } else if ( currentStep === steps.length - 1 && ! isComplete ) { setIsComplete( true ); } else if ( isComplete ) { setIsComplete( false ); - updateArgs( { currentStep: 1 } ); + updateArgs( { currentStep: 0 } ); } }, [ setIsComplete, updateArgs, isComplete, currentStep ] ); @@ -30,15 +30,15 @@ export const Factory = { { steps.map( ( step, index ) => index + 1 || isComplete } - isActive={ currentStep === index + 1 } + isComplete={ currentStep > index || isComplete } + isActive={ currentStep === index } /> ) } ; @@ -50,7 +50,6 @@ export default { component: Stepper, argTypes: { className: { control: "text" }, - numberOfSteps: { control: "number" }, currentStep: { control: "number" }, }, parameters: { @@ -60,7 +59,6 @@ export default { }, args: { className: "yst-mb-5", - numberOfSteps: 4, - currentStep: 1, + currentStep: 0, }, }; From 0aa012866d39b42f60841f7f4c24122796a85da1 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Thu, 6 Feb 2025 12:10:11 +0200 Subject: [PATCH 76/85] abstracted cta button and stepper --- .../components/site-kit-setup-widget.js | 111 +++++++----------- .../integrations-page/site-kit-integration.js | 73 +++++------- .../components/site-kit-setup-widget.test.js | 4 +- .../SiteKitIntegration.test.js | 4 +- 4 files changed, 80 insertions(+), 112 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index b7dc072140f..bbbed365876 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -4,62 +4,6 @@ import { __ } from "@wordpress/i18n"; import { CheckCircleIcon } from "@heroicons/react/solid"; import { ArrowRightIcon, XIcon, TrashIcon } from "@heroicons/react/outline"; -/** - * Get the button and stepper props based on the current state. - * - * @param {boolean} isInstalled Whether the plugin is isInstalled. - * @param {boolean} isActive Whether the feature is active. - * @param {boolean} isSetupCompleted Whether the setup is complete. - * @param {boolean} isConnected Whether the connection is active. - * @param {string} installUrl The URL to install Site Kit. - * @param {string} activateUrl The URL to activate Site Kit. - * @param {string} setupUrl The URL to setup Site Kit. - * - * @returns {Object} The button and stepper props. - */ -const getButtonAndStepperProps = ( isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, setupUrl ) => { - let buttonProps; - let currentStep; - let isComplete = false; - - switch ( true ) { - case ( ! isInstalled ): - currentStep = 1; - buttonProps = { - children: __( "Install Site Kit by Google", "wordpress-seo" ), - as: "a", - href: installUrl, - }; - break; - case ( ! isActive ): - currentStep = 2; - buttonProps = { - children: __( "Activate Site Kit by Google", "wordpress-seo" ), - as: "a", - href: activateUrl, - }; - break; - case ( ! isSetupCompleted ): - currentStep = 3; - buttonProps = { - children: __( "Set up Site Kit by Google", "wordpress-seo" ), - as: "a", - href: setupUrl, - }; - break; - case ( ! isConnected ): - currentStep = 4; - buttonProps = { children: __( "Connect Site Kit by Google", "wordpress-seo" ) }; - break; - case isConnected: - isComplete = true; - currentStep = 4; - buttonProps = { children: "Take a quick tour" }; - break; - } - return { buttonProps, currentStep, isComplete }; -}; - const steps = [ __( "INSTALL", "wordpress-seo" ), __( "ACTIVATE", "wordpress-seo" ), @@ -95,9 +39,34 @@ export const SiteKitSetupWidget = ( { onRemovePermanently, learnMorelink, } ) => { - const { buttonProps, currentStep, isComplete } = getButtonAndStepperProps( - isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, setupUrl ); - return + const stepsStatuses = [ isInstalled, isActive, isSetupCompleted, isConnected ]; + + const currentStep = stepsStatuses.findIndex( status => ! status ) >= 0 ? stepsStatuses.findIndex( status => ! status ) : stepsStatuses.length - 1; + + const lastStepCompleted = currentStep + 1 === steps.length && isConnected; + + const buttonProps = [ + { + children: __( "Install Site Kit by Google", "wordpress-seo" ), + href: installUrl, + as: "a", + }, + { + children: __( "Activate Site Kit by Google", "wordpress-seo" ), + href: activateUrl, + as: "a", + }, + { + children: __( "Set up Site Kit by Google", "wordpress-seo" ), + href: setupUrl, + as: "a", + }, + { + children: __( "Connect Site Kit by Google", "wordpress-seo" ), + }, + ]; + + return @@ -123,8 +92,8 @@ export const SiteKitSetupWidget = ( { { steps.map( ( label, index ) => ( index + 1 || isComplete } + isActive={ currentStep === index } + isComplete={ currentStep > index || lastStepCompleted } /> ) ) }
@@ -143,13 +112,21 @@ export const SiteKitSetupWidget = ( {
- - : + { lastStepCompleted + ? <> + + + + : <> + + }
; diff --git a/packages/js/src/integrations-page/site-kit-integration.js b/packages/js/src/integrations-page/site-kit-integration.js index b77556bab03..8a55097b4b4 100644 --- a/packages/js/src/integrations-page/site-kit-integration.js +++ b/packages/js/src/integrations-page/site-kit-integration.js @@ -1,6 +1,6 @@ import { __, sprintf } from "@wordpress/i18n"; import { CheckIcon } from "@heroicons/react/solid"; -import { createInterpolateElement, useCallback } from "@wordpress/element"; +import { createInterpolateElement } from "@wordpress/element"; import PropTypes from "prop-types"; import { SimpleIntegration } from "./simple-integration"; import { ReactComponent as SiteKitLogo } from "../../images/site-kit-logo.svg"; @@ -61,47 +61,33 @@ const SuccessfullyConnected = () => { export const SiteKitIntegration = ( { isActive, isSetupCompleted, isInstalled, isConnected, installUrl, activateUrl, setupUrl } ) => { const [ isModalOpen, toggleModal ] = useToggleState( false ); const [ isDisconnectModalOpen, toggleDisconnectModal ] = useToggleState( false ); + const stepsStatuses = [ isInstalled, isActive, isSetupCompleted, isConnected ]; - const getButtonProps = useCallback( () => { - if ( ! isInstalled ) { - return { - children: __( "Install Site Kit by Google", "wordpress-seo" ), - as: "a", - href: installUrl, - }; - } - if ( ! isActive ) { - return { - children: __( "Activate Site Kit by Google", "wordpress-seo" ), - as: "a", - href: activateUrl, - }; - } - if ( ! isSetupCompleted ) { - return { - children: __( "Set up Site Kit by Google", "wordpress-seo" ), - as: "a", - href: setupUrl, - }; - } - if ( ! isConnected ) { - return { - children: __( "Connect Site Kit by Google", "wordpress-seo" ), - as: "button", - onClick: toggleModal, - }; - } - - return { - children: __( "Disconnect", "wordpress-seo" ), - as: "button", - variant: "secondary", - onClick: toggleDisconnectModal, - }; - }, [ isInstalled, isActive, isSetupCompleted, isConnected, installUrl, activateUrl, toggleModal ] ); + const currentStep = stepsStatuses.findIndex( status => ! status ) >= 0 ? stepsStatuses.findIndex( status => ! status ) : stepsStatuses.length - 1; + const buttonProps = [ + { + children: __( "Install Site Kit by Google", "wordpress-seo" ), + href: installUrl, + as: "a", + }, + { + children: __( "Activate Site Kit by Google", "wordpress-seo" ), + href: activateUrl, + as: "a", + }, + { + children: __( "Set up Site Kit by Google", "wordpress-seo" ), + href: setupUrl, + as: "a", + }, + { + children: __( "Connect Site Kit by Google", "wordpress-seo" ), + onClick: toggleModal, + }, + ]; - const successfullyConnected = isInstalled && isActive && isSetupCompleted && isConnected; + const successfullyConnected = currentStep + 1 === stepsStatuses.length && isConnected; return ( <> - { successfullyConnected && } - + :
); }; Step.displayName = "Step"; Step.propTypes = { - label: PropTypes.string.isRequired, + children: PropTypes.node.isRequired, isActive: PropTypes.bool.isRequired, isComplete: PropTypes.bool.isRequired, }; diff --git a/packages/ui-library/src/components/stepper/stories.js b/packages/ui-library/src/components/stepper/stories.js index 4f528ae3851..1fd0cede4b2 100644 --- a/packages/ui-library/src/components/stepper/stories.js +++ b/packages/ui-library/src/components/stepper/stories.js @@ -29,10 +29,11 @@ export const Factory = { { steps.map( ( step, index ) => index || isComplete } isActive={ currentStep === index } - /> ) } + > + { step } + ) } From e0ccf23112e592ec489ef4e021ec35581abe60b8 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Thu, 6 Feb 2025 12:52:26 +0200 Subject: [PATCH 80/85] relocate widget to avoid shrinking on large screen --- packages/js/src/dashboard/components/dashboard.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/js/src/dashboard/components/dashboard.js b/packages/js/src/dashboard/components/dashboard.js index 4ac86adc195..a1b1935a457 100644 --- a/packages/js/src/dashboard/components/dashboard.js +++ b/packages/js/src/dashboard/components/dashboard.js @@ -47,13 +47,13 @@ export const Dashboard = ( { contentTypes, userName, features, endpoints, header return ( <> + { showGoogleSiteKit && siteKitConfiguration.isFeatureEnabled && }
- { showGoogleSiteKit && siteKitConfiguration.isFeatureEnabled && } { features.indexables && features.seoAnalysis && ( ) } From 11b7cc18533b91fb8f2e46bc138b22ce4ddd03f5 Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Thu, 6 Feb 2025 14:34:53 +0200 Subject: [PATCH 81/85] add keydown focus styling and removed z index --- .../src/components/dropdown-menu/index.js | 18 ++++++++++-------- .../src/components/dropdown-menu/stories.js | 8 ++++++-- .../src/components/dropdown-menu/style.css | 1 - 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/ui-library/src/components/dropdown-menu/index.js b/packages/ui-library/src/components/dropdown-menu/index.js index 4f2940262b7..5b7b0ada33c 100644 --- a/packages/ui-library/src/components/dropdown-menu/index.js +++ b/packages/ui-library/src/components/dropdown-menu/index.js @@ -15,14 +15,16 @@ import { Button } from "../../index"; */ const ButtonItem = ( { children, className, ...props } ) => { return ( - - { children } + + { ( { active } ) => ( + + ) } ); }; diff --git a/packages/ui-library/src/components/dropdown-menu/stories.js b/packages/ui-library/src/components/dropdown-menu/stories.js index 7adf2faf2a4..a240e092898 100644 --- a/packages/ui-library/src/components/dropdown-menu/stories.js +++ b/packages/ui-library/src/components/dropdown-menu/stories.js @@ -8,10 +8,14 @@ export const Factory = { - Item + { ( { active } ) => ( +
Item
+ ) }
- Item + { ( { active } ) => ( +
Item
+ ) }
diff --git a/packages/ui-library/src/components/dropdown-menu/style.css b/packages/ui-library/src/components/dropdown-menu/style.css index 40bb35933c5..40d540dfb60 100644 --- a/packages/ui-library/src/components/dropdown-menu/style.css +++ b/packages/ui-library/src/components/dropdown-menu/style.css @@ -30,7 +30,6 @@ yst-border-slate-200 yst-shadow-sm yst-bg-white - yst-z-50 focus-visible:yst-outline-none; } } From 363cb2bdbf5ea2e5c2950a58d8576578d27c030a Mon Sep 17 00:00:00 2001 From: Vraja Das Date: Thu, 6 Feb 2025 14:38:27 +0200 Subject: [PATCH 82/85] refactor currentStep and overall completed --- .../src/dashboard/components/site-kit-setup-widget.js | 11 +++++++---- .../js/src/integrations-page/site-kit-integration.js | 9 +++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/js/src/dashboard/components/site-kit-setup-widget.js b/packages/js/src/dashboard/components/site-kit-setup-widget.js index f48c6346c1b..9e1171792a6 100644 --- a/packages/js/src/dashboard/components/site-kit-setup-widget.js +++ b/packages/js/src/dashboard/components/site-kit-setup-widget.js @@ -41,9 +41,12 @@ export const SiteKitSetupWidget = ( { } ) => { const stepsStatuses = [ isInstalled, isActive, isSetupCompleted, isConnected ]; - const currentStep = stepsStatuses.findIndex( status => ! status ) >= 0 ? stepsStatuses.findIndex( status => ! status ) : stepsStatuses.length - 1; + let currentStep = stepsStatuses.findIndex( status => ! status ); + const overAllCompleted = currentStep === -1; - const lastStepCompleted = currentStep + 1 === steps.length && isConnected; + if ( currentStep === -1 ) { + currentStep = steps.length - 1; + } const buttonProps = [ { @@ -92,7 +95,7 @@ export const SiteKitSetupWidget = ( { { steps.map( ( label, index ) => ( index || lastStepCompleted } + isComplete={ stepsStatuses[ index ] } > { label } ) ) } @@ -114,7 +117,7 @@ export const SiteKitSetupWidget = ( {
- { lastStepCompleted + { overAllCompleted ? <> - + : <>