diff --git a/packages/js/components/changelog/add-39875 b/packages/js/components/changelog/add-39875
new file mode 100644
index 00000000000..67e499eabf5
--- /dev/null
+++ b/packages/js/components/changelog/add-39875
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix select control dropdown menu double scroll and width
diff --git a/packages/js/components/src/experimental-select-control/menu-item.scss b/packages/js/components/src/experimental-select-control/menu-item.scss
index 9f835220792..2387a40d789 100644
--- a/packages/js/components/src/experimental-select-control/menu-item.scss
+++ b/packages/js/components/src/experimental-select-control/menu-item.scss
@@ -1,5 +1,8 @@
.woocommerce-experimental-select-control__menu-item {
- padding: $gap-small;
- margin: 0;
-}
+ padding: $gap-small;
+ margin: 0;
+ .components-base-control__field {
+ margin-bottom: 0;
+ }
+}
diff --git a/packages/js/components/src/experimental-select-control/menu.scss b/packages/js/components/src/experimental-select-control/menu.scss
index 7c1f126b447..1fa08495c05 100644
--- a/packages/js/components/src/experimental-select-control/menu.scss
+++ b/packages/js/components/src/experimental-select-control/menu.scss
@@ -2,26 +2,30 @@
position: absolute;
width: 100%;
top: 100%;
- left: 0;
+ left: -1px;
margin-top: $gap-smaller;
box-sizing: border-box;
}
.components-popover.woocommerce-experimental-select-control__popover-menu {
background: $studio-white;
- border: 1px solid $studio-gray-5;
border-radius: 3px;
display: none;
&.is-open.has-results {
display: block;
}
}
+.woocommerce-experimental-select-control__popover-menu {
+ .components-popover__content {
+ max-height: 300px;
+ overflow-y: scroll;
+ }
+}
.woocommerce-experimental-select-control__popover-menu-container {
margin: 0;
- max-height: 300px;
- overflow-y: scroll;
+ width: 100%;
- > .category-field-dropdown__item:not( :first-child ) {
+ > .category-field-dropdown__item:not(:first-child) {
.category-field-dropdown__item-content {
border-top: 1px solid $gray-200;
}
diff --git a/packages/js/components/src/experimental-select-control/menu.tsx b/packages/js/components/src/experimental-select-control/menu.tsx
index 2587e8422f2..0f106acfc58 100644
--- a/packages/js/components/src/experimental-select-control/menu.tsx
+++ b/packages/js/components/src/experimental-select-control/menu.tsx
@@ -7,7 +7,6 @@ import {
createElement,
useEffect,
useRef,
- useState,
createPortal,
Children,
useLayoutEffect,
@@ -35,21 +34,28 @@ export const Menu = ( {
position = 'bottom right',
scrollIntoViewOnOpen = false,
}: MenuProps ) => {
- const [ boundingRect, setBoundingRect ] = useState< DOMRect >();
const selectControlMenuRef = useRef< HTMLDivElement >( null );
+ const popoverRef = useRef< HTMLDivElement >( null );
useLayoutEffect( () => {
- if (
- selectControlMenuRef.current?.parentElement &&
- selectControlMenuRef.current?.parentElement.clientWidth > 0
- ) {
- setBoundingRect(
- selectControlMenuRef.current.parentElement.getBoundingClientRect()
+ const comboboxWrapper = selectControlMenuRef.current?.closest(
+ '.woocommerce-experimental-select-control__combo-box-wrapper'
+ );
+ const popoverContent =
+ popoverRef.current?.querySelector< HTMLDivElement >(
+ '.components-popover__content'
);
+ if ( comboboxWrapper && comboboxWrapper?.clientWidth > 0 ) {
+ if ( popoverContent ) {
+ popoverContent.style.width = `${
+ comboboxWrapper.getBoundingClientRect().width
+ }px`;
+ }
}
}, [
selectControlMenuRef.current,
selectControlMenuRef.current?.clientWidth,
+ popoverRef.current,
] );
// Scroll the selected item into view when the menu opens.
@@ -80,6 +86,8 @@ export const Menu = ( {
) }
position={ position }
animate={ false }
+ resize={ false }
+ ref={ popoverRef }
>
// Fix to prevent select control dropdown from closing when selecting within the Popover.
e.stopPropagation()
diff --git a/packages/js/components/src/experimental-select-tree-control/select-tree-menu.tsx b/packages/js/components/src/experimental-select-tree-control/select-tree-menu.tsx
index ee13ebfeb67..04be3adfe4a 100644
--- a/packages/js/components/src/experimental-select-tree-control/select-tree-menu.tsx
+++ b/packages/js/components/src/experimental-select-tree-control/select-tree-menu.tsx
@@ -105,6 +105,7 @@ export const SelectTreeMenu = ( {
) }
position={ position }
flip={ false }
+ resize={ false }
animate={ false }
onFocusOutside={ ( event ) => {
if ( isEventOutside( event ) ) {
diff --git a/packages/js/components/src/experimental-select-tree-control/select-tree.scss b/packages/js/components/src/experimental-select-tree-control/select-tree.scss
index 8c1c78cf8ca..53dd05c346b 100644
--- a/packages/js/components/src/experimental-select-tree-control/select-tree.scss
+++ b/packages/js/components/src/experimental-select-tree-control/select-tree.scss
@@ -1,16 +1,28 @@
.woocommerce-experimental-select-control__combo-box-wrapper {
&:focus {
- box-shadow: 0 0 0 1px var( --wp-admin-theme-color );
- border-color: var( --wp-admin-theme-color );
+ box-shadow: 0 0 0 1px var(--wp-admin-theme-color);
+ border-color: var(--wp-admin-theme-color);
}
}
.woocommerce-experimental-select-tree-control__dropdown {
display: block;
+
+ .experimental-woocommerce-tree.experimental-woocommerce-tree--level-1 {
+ border-top: none;
+ border-right: none;
+ border-left: none;
+ border-radius: 0;
+ }
+
+ .experimental-woocommerce-tree-item__label {
+ margin-bottom: 0;
+ }
}
// That's the only way I could remove the padding from the @wordpress/components Dropdown.
-.woocommerce-experimental-select-tree-control__dropdown-content .components-popover__content {
+.woocommerce-experimental-select-tree-control__dropdown-content
+ .components-popover__content {
padding: 0;
}
diff --git a/packages/js/product-editor/changelog/add-39875 b/packages/js/product-editor/changelog/add-39875
new file mode 100644
index 00000000000..4173a1e63ed
--- /dev/null
+++ b/packages/js/product-editor/changelog/add-39875
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix attributes dropdown jumping when focusing on add new attribute modal shown
diff --git a/packages/js/product-editor/src/components/attribute-control/edit-attribute-modal.tsx b/packages/js/product-editor/src/components/attribute-control/edit-attribute-modal.tsx
index 69628addb9c..d6f4f52a0b5 100644
--- a/packages/js/product-editor/src/components/attribute-control/edit-attribute-modal.tsx
+++ b/packages/js/product-editor/src/components/attribute-control/edit-attribute-modal.tsx
@@ -8,8 +8,11 @@ import {
CheckboxControl,
TextControl,
} from '@wordpress/components';
-import { useState, createElement } from '@wordpress/element';
-import { __experimentalTooltip as Tooltip } from '@woocommerce/components';
+import { useState, createElement, Fragment } from '@wordpress/element';
+import {
+ __experimentalTooltip as Tooltip,
+ __experimentalSelectControlMenuSlot as SelectControlMenuSlot,
+} from '@woocommerce/components';
/**
* Internal dependencies
@@ -82,122 +85,129 @@ export const EditAttributeModal: React.FC< EditAttributeModalProps > = ( {
const isCustomAttribute = editableAttribute?.id === 0;
return (
- onCancel() }
- className="woocommerce-edit-attribute-modal"
- >
-
-
- setEditableAttribute( {
- ...( editableAttribute as EnhancedProductAttribute ),
- name: val,
- } )
- }
- />
-
- { ! isCustomAttribute
- ? globalAttributeHelperMessage
- : customAttributeHelperMessage }
-
- { attribute.terms ? (
- {
+ <>
+ onCancel() }
+ className="woocommerce-edit-attribute-modal"
+ >
+
+
setEditableAttribute( {
...( editableAttribute as EnhancedProductAttribute ),
- terms: val,
- } );
- } }
+ name: val,
+ } )
+ }
/>
- ) : (
- {
- setEditableAttribute( {
- ...( editableAttribute as EnhancedProductAttribute ),
- options: val,
- } );
- } }
- />
- ) }
-
-
- { attribute.variation && (
-
-
- setEditableAttribute( {
- ...( editableAttribute as EnhancedProductAttribute ),
- isDefault: checked,
- } )
- }
- checked={ editableAttribute?.isDefault }
- label={ isDefaultLabel }
- />
-
-
- ) }
-
-
-
+
+ { ! isCustomAttribute
+ ? globalAttributeHelperMessage
+ : customAttributeHelperMessage }
+
+ { attribute.terms ? (
+ {
setEditableAttribute( {
...( editableAttribute as EnhancedProductAttribute ),
- visible: val,
- } )
- }
- checked={ editableAttribute?.visible }
- label={ visibleLabel }
+ terms: val,
+ } );
+ } }
/>
-
-
- { attribute.id !== 0 && (
- /* Only supported for global attributes, and disabled for now as the 'Filter by Attributes' block does not support this yet. */
+ ) : (
+
{
+ setEditableAttribute( {
+ ...( editableAttribute as EnhancedProductAttribute ),
+ options: val,
+ } );
+ } }
+ />
+ ) }
+
+
+ { attribute.variation && (
+
+
+ setEditableAttribute( {
+ ...( editableAttribute as EnhancedProductAttribute ),
+ isDefault: checked,
+ } )
+ }
+ checked={ editableAttribute?.isDefault }
+ label={ isDefaultLabel }
+ />
+
+
+ ) }
+
{
- // Disabled.
- } }
- checked={ true }
- label={ useAsFilterLabel }
+ onChange={ ( val ) =>
+ setEditableAttribute( {
+ ...( editableAttribute as EnhancedProductAttribute ),
+ visible: val,
+ } )
+ }
+ checked={ editableAttribute?.visible }
+ label={ visibleLabel }
/>
-
+
- ) }
+ { attribute.id !== 0 && (
+ /* Only supported for global attributes, and disabled for now as the 'Filter by Attributes' block does not support this yet. */
+
+ {
+ // Disabled.
+ } }
+ checked={ true }
+ label={ useAsFilterLabel }
+ />
+
+
+ ) }
+
-
-
- onCancel() }
- >
- { cancelLabel }
-
- {
- onEdit( editableAttribute as EnhancedProductAttribute );
- } }
- >
- { updateLabel }
-
-
-
+
+ onCancel() }
+ >
+ { cancelLabel }
+
+ {
+ onEdit(
+ editableAttribute as EnhancedProductAttribute
+ );
+ } }
+ >
+ { updateLabel }
+
+
+
+
+ >
);
};
diff --git a/packages/js/product-editor/src/components/attribute-control/new-attribute-modal.tsx b/packages/js/product-editor/src/components/attribute-control/new-attribute-modal.tsx
index 9c7a36adc51..35243a31b06 100644
--- a/packages/js/product-editor/src/components/attribute-control/new-attribute-modal.tsx
+++ b/packages/js/product-editor/src/components/attribute-control/new-attribute-modal.tsx
@@ -220,8 +220,11 @@ export const NewAttributeModal: React.FC< NewAttributeModalProps > = ( {
document.querySelector< HTMLLabelElement >(
'.woocommerce-new-attribute-modal__table-row .woocommerce-attribute-input-field label'
);
+ const timeoutId = setTimeout( () => {
+ firstAttributeFieldLabel?.focus();
+ }, 100 );
- firstAttributeFieldLabel?.focus();
+ return () => clearTimeout( timeoutId );
}, [] );
return (