Remove the wc combobox component, it is no longer used (#50975)

This commit is contained in:
Sam Seay 2024-09-03 17:20:46 +08:00 committed by GitHub
parent a0cb19b550
commit 115d4f16c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 10 additions and 358 deletions

View File

@ -1,162 +0,0 @@
/**
* External dependencies
*/
import clsx from 'clsx';
import { __ } from '@wordpress/i18n';
import { useEffect, useId, useRef } from '@wordpress/element';
import { ComboboxControl } from 'wordpress-components';
import { ValidationInputError } from '@woocommerce/blocks-components';
import { isObject } from '@woocommerce/types';
import { useDispatch, useSelect } from '@wordpress/data';
import { VALIDATION_STORE_KEY } from '@woocommerce/block-data';
/**
* Internal dependencies
*/
import './style.scss';
export interface ComboboxControlOption {
label: string;
value: string;
}
export interface ComboboxProps {
autoComplete?: string | undefined;
className?: string;
errorId: string | null;
errorMessage?: string | undefined;
id: string;
instanceId?: string;
label?: string | undefined;
onChange: ( filterValue: string ) => void;
options: ComboboxControlOption[];
required?: boolean | undefined;
value: string;
}
/**
* Wrapper for the WordPress ComboboxControl which supports validation.
*/
const Combobox = ( {
id,
className,
label,
onChange,
options,
value,
required = false,
errorId: incomingErrorId,
autoComplete = 'off',
errorMessage = __( 'Please select a valid option', 'woocommerce' ),
}: ComboboxProps ): JSX.Element => {
const controlRef = useRef< HTMLDivElement >( null );
const fallbackId = useId();
const controlId = id || 'control-' + fallbackId;
const errorId = incomingErrorId || controlId;
const { setValidationErrors, clearValidationError } =
useDispatch( VALIDATION_STORE_KEY );
const { error, validationErrorId } = useSelect( ( select ) => {
const store = select( VALIDATION_STORE_KEY );
return {
error: store.getValidationError( errorId ),
validationErrorId: store.getValidationErrorId( errorId ),
};
} );
useEffect( () => {
if ( ! required || value ) {
clearValidationError( errorId );
} else {
setValidationErrors( {
[ errorId ]: {
message: errorMessage,
hidden: true,
},
} );
}
return () => {
clearValidationError( errorId );
};
}, [
clearValidationError,
value,
errorId,
errorMessage,
required,
setValidationErrors,
] );
// @todo Remove patch for ComboboxControl once https://github.com/WordPress/gutenberg/pull/33928 is released
// Also see https://github.com/WordPress/gutenberg/pull/34090
return (
<div
id={ controlId }
className={ clsx( 'wc-block-components-combobox', className, {
'is-active': value,
'has-error': error?.message && ! error?.hidden,
} ) }
ref={ controlRef }
>
<ComboboxControl
className={ 'wc-block-components-combobox-control' }
label={ label }
onChange={ onChange }
onFilterValueChange={ ( filterValue: string ) => {
if ( filterValue.length ) {
// If we have a value and the combobox is not focussed, this could be from browser autofill.
const activeElement = isObject( controlRef.current )
? controlRef.current.ownerDocument.activeElement
: undefined;
if (
activeElement &&
isObject( controlRef.current ) &&
controlRef.current.contains( activeElement )
) {
return;
}
// Try to match.
const normalizedFilterValue =
filterValue.toLocaleUpperCase();
// Try to find an exact match first using values.
const foundValue = options.find(
( option ) =>
option.value.toLocaleUpperCase() ===
normalizedFilterValue
);
if ( foundValue ) {
onChange( foundValue.value );
return;
}
// Fallback to a label match.
const foundOption = options.find( ( option ) =>
option.label
.toLocaleUpperCase()
.startsWith( normalizedFilterValue )
);
if ( foundOption ) {
onChange( foundOption.value );
}
}
} }
options={ options }
value={ value || '' }
allowReset={ false }
autoComplete={ autoComplete }
// Note these aria properties are ignored by ComboboxControl. When we replace ComboboxControl we should support them.
aria-invalid={ error?.message && ! error?.hidden }
aria-errormessage={ validationErrorId }
/>
<ValidationInputError propertyName={ errorId } />
</div>
);
};
export default Combobox;

View File

@ -1,188 +0,0 @@
// For when the Combobox is being used as a select custom field.
.wc-block-components-select-input {
position: relative;
margin-top: $gap;
}
.wc-block-components-form .wc-block-components-combobox,
.wc-block-components-combobox {
.wc-block-components-combobox-control {
@include reset-typography();
@include reset-box();
// Fixes width in the editor.
.components-flex {
width: 100%;
}
.components-base-control__field {
@include reset-box();
position: relative;
}
.components-combobox-control__suggestions-container {
@include reset-typography();
@include reset-box();
position: relative;
}
input.components-combobox-control__input {
@include reset-typography();
@include font-size(regular);
padding: em($gap + $gap-smaller) em($gap-smaller) em($gap-smaller);
line-height: em($gap);
box-sizing: border-box;
outline: inherit;
border: 1px solid $input-border-gray;
background: #fff;
box-shadow: none;
color: $input-text-active;
font-family: inherit;
font-weight: normal;
letter-spacing: inherit;
text-align: left;
text-overflow: ellipsis;
text-transform: none;
white-space: nowrap;
width: 100%;
opacity: initial;
border-radius: $universal-border-radius;
height: 50px;
&[aria-expanded="true"],
&:focus {
background-color: #fff;
color: $input-text-active;
outline: 0;
box-shadow: 0 0 0 1px $input-border-gray;
}
&[aria-expanded="true"] {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.has-dark-controls & {
background-color: $input-background-dark;
border-color: $input-border-dark;
color: $input-text-dark;
&:focus {
background-color: $input-background-dark;
color: $input-text-dark;
box-shadow: 0 0 0 1px $input-border-dark;
}
}
}
.components-form-token-field__suggestions-list {
position: absolute;
z-index: 10;
background-color: $select-dropdown-light;
border: 1px solid $input-border-gray;
border-top: 0;
border-bottom: 0;
margin: 3em 0 0 0;
padding: 0;
max-height: 300px;
min-width: 100%;
overflow: auto;
color: currentColor;
border-bottom-left-radius: $universal-border-radius;
border-bottom-right-radius: $universal-border-radius;
box-shadow: 0 1px 0 1px $input-border-gray;
box-sizing: border-box;
.has-dark-controls & {
background-color: $select-dropdown-dark;
color: $input-text-dark;
}
.components-form-token-field__suggestion {
@include font-size(regular);
color: $gray-700;
cursor: default;
list-style: none;
margin: 0;
padding: em($gap-smallest) $gap;
&.is-selected {
background-color: $gray-300;
.has-dark-controls & {
background-color: $select-item-dark;
}
}
// Force empty rows to have a height.
&::after {
content: " ";
display: inline-block;
}
&:hover,
&:focus,
&.is-highlighted,
&:active {
background-color: #00669e;
color: #fff;
}
}
}
label.components-base-control__label {
@include reset-typography();
@include font-size(regular);
position: absolute;
transform: translateY(em($gap));
line-height: 1.25; // =20px when font-size is 16px.
left: em($gap-smaller);
top: -2px;
transform-origin: top left;
transition: all 200ms ease;
color: $universal-body-low-emphasis;
z-index: 1;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
max-width: calc(100% - #{2 * $gap});
white-space: nowrap;
.has-dark-controls & {
color: $input-placeholder-dark;
}
@media screen and (prefers-reduced-motion: reduce) {
transition: none;
}
}
}
.wc-block-components-combobox-control:has(input:-webkit-autofill) {
label {
transform: translateY(#{$gap-smallest}) scale(0.75);
}
}
&.is-active,
&:focus-within {
.wc-block-components-combobox-control
label.components-base-control__label {
transform: translateY(#{$gap-smallest}) scale(0.75);
}
}
&.has-error {
.wc-block-components-combobox-control {
label.components-base-control__label {
color: $alert-red;
}
input.components-combobox-control__input {
&,
&:hover,
&:focus,
&:active {
border-color: $alert-red;
}
&:focus {
box-shadow: 0 0 0 1px $alert-red;
}
}
}
}
}

View File

@ -1,10 +1,10 @@
/** /**
* Internal dependencies * Internal dependencies
*/ */
import { ComboboxProps } from '../combobox'; import { SelectProps } from '../select';
import { countries } from './stories/countries-filler'; import { countries } from './stories/countries-filler';
export interface CountryInputProps extends Omit< ComboboxProps, 'options' > { export interface CountryInputProps extends Omit< SelectProps, 'options' > {
/** /**
* Classes to assign to the wrapper component of the input * Classes to assign to the wrapper component of the input
*/ */
@ -12,7 +12,7 @@ export interface CountryInputProps extends Omit< ComboboxProps, 'options' > {
/** /**
* Whether input elements can by default have their values automatically completed by the browser. * Whether input elements can by default have their values automatically completed by the browser.
* *
* This value gets assigned to both the wrapper `Combobox` and the wrapped input element. * This value gets assigned to both the wrapper `Select` and the wrapped input element.
*/ */
autoComplete?: string | undefined; autoComplete?: string | undefined;
} }

View File

@ -1,6 +1,5 @@
@import "node_modules/@wordpress/base-styles/breakpoints"; @import "node_modules/@wordpress/base-styles/breakpoints";
@import "node_modules/@wordpress/base-styles/mixins"; @import "node_modules/@wordpress/base-styles/mixins";
@import "node_modules/wordpress-components/src/combobox-control/style";
.wc-block-components-country-input { .wc-block-components-country-input {
margin-top: $gap; margin-top: $gap;

View File

@ -1,7 +1,6 @@
export { default as BlockErrorBoundary } from './block-error-boundary'; export { default as BlockErrorBoundary } from './block-error-boundary';
export * from './button'; export * from './button';
export * from './cart-checkout'; export * from './cart-checkout';
export * from './combobox';
export * from './country-input'; export * from './country-input';
export * from './drawer'; export * from './drawer';
export { default as FilterElementLabel } from './filter-element-label'; export { default as FilterElementLabel } from './filter-element-label';

View File

@ -20,7 +20,7 @@ export type SelectOption = {
disabled?: boolean; disabled?: boolean;
}; };
type SelectProps = Omit< export type SelectProps = Omit<
React.SelectHTMLAttributes< HTMLSelectElement >, React.SelectHTMLAttributes< HTMLSelectElement >,
'onChange' 'onChange'
> & { > & {

View File

@ -1,13 +1,13 @@
/** /**
* External dependencies * External dependencies
*/ */
import { ComboboxControlOption } from '@woocommerce/base-components/combobox';
import type { AllHTMLAttributes, AriaAttributes } from 'react'; import type { AllHTMLAttributes, AriaAttributes } from 'react';
/** /**
* Internal dependencies * Internal dependencies
*/ */
import { getSetting } from './utils'; import { getSetting } from './utils';
import { SelectOption } from '../../base/components';
// A list of attributes that can be added to a custom field when registering it. // A list of attributes that can be added to a custom field when registering it.
type CustomFieldAttributes = Pick< type CustomFieldAttributes = Pick<
@ -39,7 +39,7 @@ export interface FormField {
// The type of input to render. Defaults to text. // The type of input to render. Defaults to text.
type?: string; type?: string;
// The options if this is a select field // The options if this is a select field
options?: ComboboxControlOption[]; options?: SelectOption[];
// The placeholder for the field, only applicable for select fields. // The placeholder for the field, only applicable for select fields.
placeholder?: string; placeholder?: string;
// Additional attributes added when registering a field. String in key is required for data attributes. // Additional attributes added when registering a field. String in key is required for data attributes.

View File

@ -0,0 +1,4 @@
Significance: minor
Type: dev
Remove @wooocommerce `Combobox` component that is no longer used.