diff --git a/client/landing/gutenboarding/components/domain-picker-button/index.tsx b/client/landing/gutenboarding/components/domain-picker-button/index.tsx
index 2b5c01aca65191..e621278a995d96 100644
--- a/client/landing/gutenboarding/components/domain-picker-button/index.tsx
+++ b/client/landing/gutenboarding/components/domain-picker-button/index.tsx
@@ -2,12 +2,13 @@
* External dependencies
*/
import * as React from 'react';
+import classnames from 'classnames';
import { Button } from '@wordpress/components';
import { Icon, chevronDown } from '@wordpress/icons';
-import { useDispatch, useSelect } from '@wordpress/data';
+import { useSelect, useDispatch } from '@wordpress/data';
import { useI18n } from '@automattic/react-i18n';
-import classnames from 'classnames';
import type { DomainSuggestions } from '@automattic/data-stores';
+import DomainPicker from '@automattic/domain-picker';
/**
* Internal dependencies
@@ -16,10 +17,7 @@ import DomainPickerPopover from '../domain-picker-popover';
import DomainPickerModal from '../domain-picker-modal';
import { FLOW_ID } from '../../constants';
import { STORE_KEY } from '../../stores/onboard';
-import { useDomainSuggestions } from '../../hooks/use-domain-suggestions';
-import { DOMAIN_SUGGESTIONS_STORE } from '../../stores/domain-suggestions';
import { getSuggestionsVendor } from 'lib/domains/suggestions';
-
const DOMAIN_SUGGESTION_VENDOR = getSuggestionsVendor( true );
/**
@@ -42,91 +40,71 @@ const DomainPickerButton: React.FunctionComponent< Props > = ( {
currentDomain,
...buttonProps
} ) => {
- const buttonRef = React.createRef< HTMLButtonElement >();
-
- const domainSuggestions = useDomainSuggestions( { locale: useI18n().i18nLocale, quantity: 10 } );
-
- const domainCategories = useSelect( ( select ) =>
- select( DOMAIN_SUGGESTIONS_STORE ).getCategories()
- );
+ const { __ } = useI18n();
- const { domainSearch, domainCategory } = useSelect( ( select ) =>
- select( STORE_KEY ).getState()
- );
- const { setDomainSearch, setDomainCategory } = useDispatch( STORE_KEY );
+ const buttonRef = React.createRef< HTMLButtonElement >();
- const [ isDomainPopoverVisible, setDomainPopoverVisibility ] = React.useState( false );
- const [ isDomainModalVisible, setDomainModalVisibility ] = React.useState( false );
+ const [ domainPickerMode, setDomainPickerMode ] = React.useState<
+ 'popover' | 'modal' | undefined
+ >();
- const handlePopoverClose = ( e?: React.FocusEvent ) => {
- // Don't collide with button toggling
- if ( e?.relatedTarget === buttonRef.current ) {
- return;
- }
- setDomainPopoverVisibility( false );
+ const handlePopoverToggle = () => {
+ setDomainPickerMode( ( mode ) => ( mode ? undefined : 'popover' ) );
};
- const handleModalClose = () => {
- setDomainModalVisibility( false );
+ const handleClose = () => {
+ setDomainPickerMode( undefined );
};
- const handleMoreOptions = () => {
- setDomainPopoverVisibility( false );
- setDomainModalVisibility( true );
+ const onClickMoreOptions = () => {
+ setDomainPickerMode( 'modal' );
};
+ const domainSearch = useSelect( ( select ) => select( STORE_KEY ).getDomainSearch() );
+ const { setDomainSearch } = useDispatch( STORE_KEY );
+
+ const domainPicker = (
+
+ );
+
return (
<>
-
+ isOpen={ domainPickerMode === 'popover' }
+ onClose={ handlePopoverToggle }
+ >
+ { domainPicker }
+
+
+ { domainPicker }
+
>
);
};
diff --git a/client/landing/gutenboarding/components/domain-picker-modal/index.tsx b/client/landing/gutenboarding/components/domain-picker-modal/index.tsx
index b7709bed68ee21..606e7cc4d037c4 100644
--- a/client/landing/gutenboarding/components/domain-picker-modal/index.tsx
+++ b/client/landing/gutenboarding/components/domain-picker-modal/index.tsx
@@ -4,7 +4,6 @@
import * as React from 'react';
import Modal from 'react-modal';
import { select } from '@wordpress/data';
-import DomainPicker, { Props as DomainPickerProps } from '@automattic/domain-picker';
/**
* Internal dependencies
@@ -17,11 +16,13 @@ import { STORE_KEY } from '../../stores/onboard';
*/
import './style.scss';
-interface Props extends DomainPickerProps {
+interface Props {
+ onClose: Function;
isOpen: boolean;
+ children: any;
}
-const DomainPickerModal: React.FunctionComponent< Props > = ( { isOpen, onClose, ...props } ) => {
+const DomainPickerModal: React.FunctionComponent< Props > = ( { isOpen, onClose, children } ) => {
if ( ! isOpen ) {
return null;
}
@@ -54,13 +55,7 @@ const DomainPickerModal: React.FunctionComponent< Props > = ( { isOpen, onClose,
overlayClassName="domain-picker-modal-overlay"
bodyOpenClassName="has-domain-picker-modal"
>
-
+ { children }
);
};
diff --git a/client/landing/gutenboarding/components/domain-picker-modal/style.scss b/client/landing/gutenboarding/components/domain-picker-modal/style.scss
index b05e15fad79a47..40ab7ba353c749 100644
--- a/client/landing/gutenboarding/components/domain-picker-modal/style.scss
+++ b/client/landing/gutenboarding/components/domain-picker-modal/style.scss
@@ -5,7 +5,7 @@
@include onboarding-modal-overlay;
}
-.domain-picker-modal {
+.is-section-gutenboarding .domain-picker-modal {
.domain-picker__panel-row-main {
diff --git a/client/landing/gutenboarding/components/domain-picker-popover/index.tsx b/client/landing/gutenboarding/components/domain-picker-popover/index.tsx
index 7994d10e2e21de..c1f20deab483e0 100644
--- a/client/landing/gutenboarding/components/domain-picker-popover/index.tsx
+++ b/client/landing/gutenboarding/components/domain-picker-popover/index.tsx
@@ -5,7 +5,6 @@ import * as React from 'react';
import { Popover } from '@wordpress/components';
import { useViewportMatch } from '@wordpress/compose';
import { select } from '@wordpress/data';
-import DomainPicker, { Props as DomainPickerProps } from '@automattic/domain-picker';
/**
* Internal dependencies
@@ -18,11 +17,13 @@ import { STORE_KEY } from '../../stores/onboard';
*/
import './style.scss';
-interface Props extends DomainPickerProps {
+interface Props {
+ onClose: Function;
isOpen: boolean;
+ children: any;
}
-const DomainPickerPopover: React.FunctionComponent< Props > = ( { isOpen, onClose, ...props } ) => {
+const DomainPickerPopover: React.FunctionComponent< Props > = ( { isOpen, onClose, children } ) => {
// Popover expands at medium viewport width
const isMobile = useViewportMatch( 'medium', '<' );
@@ -59,7 +60,7 @@ const DomainPickerPopover: React.FunctionComponent< Props > = ( { isOpen, onClos
position={ 'bottom center' }
expandOnMobile={ true }
>
-
+ { children }
);
diff --git a/client/landing/gutenboarding/stores/onboard/selectors.ts b/client/landing/gutenboarding/stores/onboard/selectors.ts
index bece8ae98efe82..61f588dbffc71d 100644
--- a/client/landing/gutenboarding/stores/onboard/selectors.ts
+++ b/client/landing/gutenboarding/stores/onboard/selectors.ts
@@ -1,7 +1,13 @@
+/**
+ * External dependencies
+ */
+import { select } from '@wordpress/data';
+
/**
* Internal dependencies
*/
import type { State } from './reducer';
+import { USER_STORE } from '../user';
export const getIsRedirecting = ( state: State ) => state.isRedirecting;
export const getState = ( state: State ) => state;
@@ -23,3 +29,8 @@ export const getSelectedFonts = ( state: State ) => state.selectedFonts;
export const getSelectedVertical = ( state: State ) => state.siteVertical;
export const getSelectedDomain = ( state: State ) => state.domain;
export const getSelectedSiteTitle = ( state: State ) => state.siteTitle;
+export const getDomainSearch = ( state: State ) =>
+ state.domainSearch ||
+ getSelectedSiteTitle( state ) ||
+ getSelectedVertical( state )?.label.trim() ||
+ select( USER_STORE ).getCurrentUser()?.username;
diff --git a/packages/domain-picker/package.json b/packages/domain-picker/package.json
index 47fc92bc85e0e8..5784400e28b464 100644
--- a/packages/domain-picker/package.json
+++ b/packages/domain-picker/package.json
@@ -39,7 +39,8 @@
"lodash": "^4.17.15",
"tslib": "^1.10.0",
"use-debounce": "^3.1.0",
- "uuid": "^7.0.2"
+ "uuid": "^7.0.2",
+ "@wordpress/base-styles": "^1.8.0"
},
"peerDependencies": {
"@wordpress/data": "^4.18.0",
diff --git a/packages/domain-picker/src/constants.ts b/packages/domain-picker/src/constants.ts
new file mode 100644
index 00000000000000..8024fb11712fe2
--- /dev/null
+++ b/packages/domain-picker/src/constants.ts
@@ -0,0 +1,5 @@
+export const PAID_DOMAINS_TO_SHOW_WITH_CATEGORIES_MODE = 10;
+export const PAID_DOMAINS_TO_SHOW_WITHOUT_CATEGORIES_MODE = 5;
+export const DOMAIN_SEARCH_DEBOUNCE_INTERVAL = 300;
+export const DOMAIN_SUGGESTION_VENDOR = 'variation4_front';
+export const DOMAIN_SUGGESTIONS_STORE = 'automattic/domains/suggestions';
diff --git a/packages/domain-picker/src/domain-categories/index.tsx b/packages/domain-picker/src/domain-categories/index.tsx
index 13148af0ddfc36..3da37fbbbc867e 100644
--- a/packages/domain-picker/src/domain-categories/index.tsx
+++ b/packages/domain-picker/src/domain-categories/index.tsx
@@ -7,25 +7,24 @@ import { Icon, chevronDown } from '@wordpress/icons';
import classNames from 'classnames';
import { useI18n } from '@automattic/react-i18n';
import { useState } from '@wordpress/element';
+import { useSelect } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { DOMAIN_SUGGESTIONS_STORE } from '../constants';
/**
* Style dependencies
*/
import './style.scss';
-type DomainCategory = import('@automattic/data-stores').DomainSuggestions.DomainCategory;
-
export interface Props {
onSelect: ( domainCategorySlug?: string ) => void;
selected?: string;
- domainCategories: DomainCategory[];
}
-const DomainPickerCategories: React.FunctionComponent< Props > = ( {
- onSelect,
- selected,
- domainCategories,
-} ) => {
+const DomainPickerCategories: React.FunctionComponent< Props > = ( { onSelect, selected } ) => {
const { __ } = useI18n();
const [ isOpen, setIsOpen ] = useState( false );
@@ -35,6 +34,10 @@ const DomainPickerCategories: React.FunctionComponent< Props > = ( {
onSelect( slug );
};
+ const domainCategories = useSelect( ( select ) =>
+ select( DOMAIN_SUGGESTIONS_STORE ).getCategories()
+ );
+
return (
{ showDomainCategories && (
-
+
) }
@@ -260,7 +256,7 @@ const DomainPicker: FunctionComponent< Props > = ( {
) ) }
{ ! paidSuggestions &&
- times( quantity - 1, ( i ) => ) }
+ times( quantity, ( i ) => ) }
{ paidSuggestions &&
( paidSuggestions?.length ? (
paidSuggestions.map( ( suggestion, i ) => (
diff --git a/packages/domain-picker/src/domain-picker/style.scss b/packages/domain-picker/src/domain-picker/style.scss
index bbadfbd2143495..b46ebca878a328 100644
--- a/packages/domain-picker/src/domain-picker/style.scss
+++ b/packages/domain-picker/src/domain-picker/style.scss
@@ -1,7 +1,5 @@
-@import 'assets/stylesheets/gutenberg-base-styles';
-@import 'assets/stylesheets/shared/mixins/placeholder'; // Contains the placeholder mixin
-@import 'assets/stylesheets/shared/animation'; // Needed for the placeholder
-@import '../mixins';
+@import '../styles/placeholder.scss'; // Contains the placeholder mixin
+@import '../styles/mixins';
$domain-picker__suggestion-item-height: 24px;
@@ -14,6 +12,8 @@ $domain-picker__suggestion-item-height: 24px;
padding: 0;
width: 100%;
height: 100%;
+ border-top: unset;
+ border-bottom: unset;
}
.components-panel__row {
diff --git a/packages/domain-picker/src/hooks/use-domain-suggestions.ts b/packages/domain-picker/src/hooks/use-domain-suggestions.ts
new file mode 100644
index 00000000000000..666f123750867b
--- /dev/null
+++ b/packages/domain-picker/src/hooks/use-domain-suggestions.ts
@@ -0,0 +1,42 @@
+/**
+ * External dependencies
+ */
+import { useSelect } from '@wordpress/data';
+import { useDebounce } from 'use-debounce';
+
+/**
+ * Internal dependencies
+ */
+import {
+ DOMAIN_SUGGESTION_VENDOR,
+ PAID_DOMAINS_TO_SHOW_WITHOUT_CATEGORIES_MODE,
+ DOMAIN_SUGGESTIONS_STORE,
+ DOMAIN_SEARCH_DEBOUNCE_INTERVAL,
+} from '../constants';
+
+export function useDomainSuggestions(
+ searchTerm = '',
+ domainCategory?: string,
+ locale = 'en',
+ quantity = PAID_DOMAINS_TO_SHOW_WITHOUT_CATEGORIES_MODE
+) {
+ const [ domainSearch ] = useDebounce( searchTerm, DOMAIN_SEARCH_DEBOUNCE_INTERVAL );
+
+ return useSelect(
+ ( select ) => {
+ if ( ! domainSearch ) {
+ return;
+ }
+ return select( DOMAIN_SUGGESTIONS_STORE ).getDomainSuggestions( domainSearch, {
+ // Avoid `only_wordpressdotcom` — it seems to fail to find results sometimes
+ include_wordpressdotcom: true,
+ include_dotblogsubdomain: false,
+ quantity: quantity + 1, // increment the count to add the free domain
+ locale,
+ vendor: DOMAIN_SUGGESTION_VENDOR,
+ category_slug: domainCategory,
+ } );
+ },
+ [ domainSearch, domainCategory, quantity ]
+ );
+}
diff --git a/packages/domain-picker/src/styles/base-styles.scss b/packages/domain-picker/src/styles/base-styles.scss
new file mode 100644
index 00000000000000..efd1f7932c73a3
--- /dev/null
+++ b/packages/domain-picker/src/styles/base-styles.scss
@@ -0,0 +1,4 @@
+@import '~@wordpress/base-styles/colors';
+@import '~@wordpress/base-styles/breakpoints';
+@import '~@wordpress/base-styles/mixins';
+@import '~@automattic/calypso-color-schemes'
diff --git a/packages/domain-picker/src/mixins.scss b/packages/domain-picker/src/styles/mixins.scss
similarity index 75%
rename from packages/domain-picker/src/mixins.scss
rename to packages/domain-picker/src/styles/mixins.scss
index da8e5615ca0464..4bea1199a35677 100644
--- a/packages/domain-picker/src/mixins.scss
+++ b/packages/domain-picker/src/styles/mixins.scss
@@ -1,5 +1,4 @@
-@import './variables.scss';
-@import 'assets/stylesheets/gutenberg-base-styles';
+@import './base-styles.scss';
@mixin domain-picker-package--font-recoleta {
font-family: Recoleta, Georgia, 'Times New Roman', Times, serif;
diff --git a/packages/domain-picker/src/styles/placeholder.scss b/packages/domain-picker/src/styles/placeholder.scss
new file mode 100644
index 00000000000000..15ed42c0eb18e8
--- /dev/null
+++ b/packages/domain-picker/src/styles/placeholder.scss
@@ -0,0 +1,29 @@
+@import './base-styles.scss';
+
+// ==========================================================================
+// Placeholder mixin
+// Adds animation to placeholder section
+// ==========================================================================
+
+@mixin placeholder( $color-property: $light-gray-200 ) {
+ animation: domain-picker-loading-fade 1.6s ease-in-out infinite;
+ background: $color-property;
+ color: transparent;
+
+ &::after {
+ content: '\00a0';
+ }
+}
+
+// a pulsing animation for placeholders
+@keyframes domain-picker-loading-fade {
+ 0% {
+ opacity: 0.5;
+ }
+ 50% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0.5;
+ }
+}
diff --git a/packages/domain-picker/src/variables.scss b/packages/domain-picker/src/variables.scss
deleted file mode 100644
index e28701f63f0b44..00000000000000
--- a/packages/domain-picker/src/variables.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-// Reusable style variables
-$domain-picker-package-header-height: 64px;
-$domain-picker-package-heading-padding-desktop: 64px 0 80px;
-$domain-picker-package-heading-padding-mobile: 44px 0 50px;
-$domain-picker-package-block-margin-mobile: 20px;
-$domain-picker-package-block-margin-small: 44px;
-$domain-picker-package-block-margin-medium: 88px;