Remove the wc combobox component, it is no longer used (#50975)
This commit is contained in:
parent
a0cb19b550
commit
115d4f16c9
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ComboboxProps } from '../combobox';
|
||||
import { SelectProps } from '../select';
|
||||
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
|
||||
*/
|
||||
|
@ -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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
@import "node_modules/@wordpress/base-styles/breakpoints";
|
||||
@import "node_modules/@wordpress/base-styles/mixins";
|
||||
@import "node_modules/wordpress-components/src/combobox-control/style";
|
||||
|
||||
.wc-block-components-country-input {
|
||||
margin-top: $gap;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
export { default as BlockErrorBoundary } from './block-error-boundary';
|
||||
export * from './button';
|
||||
export * from './cart-checkout';
|
||||
export * from './combobox';
|
||||
export * from './country-input';
|
||||
export * from './drawer';
|
||||
export { default as FilterElementLabel } from './filter-element-label';
|
||||
|
|
|
@ -20,7 +20,7 @@ export type SelectOption = {
|
|||
disabled?: boolean;
|
||||
};
|
||||
|
||||
type SelectProps = Omit<
|
||||
export type SelectProps = Omit<
|
||||
React.SelectHTMLAttributes< HTMLSelectElement >,
|
||||
'onChange'
|
||||
> & {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { ComboboxControlOption } from '@woocommerce/base-components/combobox';
|
||||
import type { AllHTMLAttributes, AriaAttributes } from 'react';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getSetting } from './utils';
|
||||
import { SelectOption } from '../../base/components';
|
||||
|
||||
// A list of attributes that can be added to a custom field when registering it.
|
||||
type CustomFieldAttributes = Pick<
|
||||
|
@ -39,7 +39,7 @@ export interface FormField {
|
|||
// The type of input to render. Defaults to text.
|
||||
type?: string;
|
||||
// The options if this is a select field
|
||||
options?: ComboboxControlOption[];
|
||||
options?: SelectOption[];
|
||||
// The placeholder for the field, only applicable for select fields.
|
||||
placeholder?: string;
|
||||
// Additional attributes added when registering a field. String in key is required for data attributes.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: dev
|
||||
|
||||
Remove @wooocommerce `Combobox` component that is no longer used.
|
Loading…
Reference in New Issue