/** * WordPress dependencies */ import { SelectControl, TextControl } from '@safe-wordpress/components'; import { _x } from '@safe-wordpress/i18n'; /** * External dependencies */ import type { KeyValueMatch, StringMatch } from '@nelio/popups/types'; type SelectValue = 'exists' | 'does-not-exist' | StringMatch[ 'matchType' ]; const DEFAULT_STRING_MATCH: StringMatch = { matchType: 'is', matchValue: '', }; const VALUE_LABELS: Record< StringMatch[ 'matchType' ], string > = { is: _x( 'has value equal to', 'text', 'nelio-popups' ), 'is-not': _x( 'has value different from', 'text', 'nelio-popups' ), includes: _x( 'has value that includes', 'text', 'nelio-popups' ), 'does-not-include': _x( 'has value that does not include', 'text', 'nelio-popups' ), regex: _x( 'has value that matches', 'text', 'nelio-popups' ), }; const MATCH_OPTIONS = [ { value: 'exists' as const, label: _x( 'exists', 'text', 'nelio-popups' ) }, { value: 'does-not-exist' as const, label: _x( 'does not exist', 'text', 'nelio-popups' ), }, ...Object.keys( VALUE_LABELS ).map( ( value: StringMatch[ 'matchType' ] ) => ( { value, label: VALUE_LABELS[ value ], } ) ), ]; export type KeyValueMatchControlProps = { readonly keyPlaceholder?: string; readonly keyHelp?: string; readonly keyValueMatch: KeyValueMatch; readonly onKeyValueMatchChange: ( newKeyValueMatch: KeyValueMatch ) => void; }; export const KeyValueMatchControl = ( props: KeyValueMatchControlProps ): JSX.Element => { const { keyValueMatch, keyHelp, keyPlaceholder, onKeyValueMatchChange } = props; const selectedValue = getSelectValue( keyValueMatch ); const onSelectChange = ( value: SelectValue ) => { if ( value === 'exists' ) { return onKeyValueMatchChange( { exists: true, key: keyValueMatch.key, value: undefined, } ); } if ( value === 'does-not-exist' ) { return onKeyValueMatchChange( { exists: false, key: keyValueMatch.key, } ); } return onKeyValueMatchChange( { exists: true, key: keyValueMatch.key, value: { matchType: value, matchValue: getMatchValue( keyValueMatch ), }, } ); }; const textValue = keyValueMatch.exists ? keyValueMatch.value?.matchValue ?? '' : ''; const onTextChange = ( newText: string ) => onKeyValueMatchChange( { exists: true, key: keyValueMatch.key, value: { matchType: getMatchType( keyValueMatch ), matchValue: newText, }, } ); return ( <> { onKeyValueMatchChange( { ...keyValueMatch, key: newKey, } ); } } /> { selectedValue !== 'exists' && selectedValue !== 'does-not-exist' && ( ) } ); }; function getSelectValue( value: KeyValueMatch ): SelectValue { if ( ! value.exists ) { return 'does-not-exist'; } if ( ! value.value ) { return 'exists'; } return getMatchType( value ); } function getMatchType( value: KeyValueMatch ): StringMatch[ 'matchType' ] { return value.exists && value.value ? value.value.matchType : DEFAULT_STRING_MATCH.matchType; } function getMatchValue( value: KeyValueMatch ): string { return value.exists && value.value ? value.value.matchValue : DEFAULT_STRING_MATCH.matchValue; }