Add coexistence checks to all enqueue methods to prevent loading both React and Grid.js assets simultaneously. Changes: - ReactAdmin.php: Only enqueue React assets when ?react=1 - Init.php: Skip Grid.js when React active on admin pages - Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0 - Customer.php, Product.php, License.php: Add coexistence checks Now the toggle between Classic and React versions works correctly. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
138 lines
5.3 KiB
JavaScript
138 lines
5.3 KiB
JavaScript
import { createElement } from "react";
|
|
/**
|
|
* External dependencies
|
|
*/
|
|
import { View, Animated, StyleSheet, Text, TouchableOpacity, ScrollView } from 'react-native';
|
|
|
|
/**
|
|
* WordPress dependencies
|
|
*/
|
|
import { useLayoutEffect, useEffect, useRef, useState, useCallback } from '@wordpress/element';
|
|
import { __, sprintf } from '@wordpress/i18n';
|
|
import { Icon, __unstableAutocompletionItemsFill as AutocompletionItemsFill } from '@wordpress/components';
|
|
import { usePreferredColorSchemeStyle } from '@wordpress/compose';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import BackgroundView from './background-view';
|
|
import getDefaultUseItems from './get-default-use-items';
|
|
import styles from './style.scss';
|
|
const {
|
|
compose: stylesCompose
|
|
} = StyleSheet;
|
|
export function getAutoCompleterUI(autocompleter) {
|
|
const useItems = autocompleter.useItems ? autocompleter.useItems : getDefaultUseItems(autocompleter);
|
|
function AutocompleterUI({
|
|
filterValue,
|
|
selectedIndex,
|
|
onChangeOptions,
|
|
onSelect,
|
|
value,
|
|
reset
|
|
}) {
|
|
const [items] = useItems(filterValue);
|
|
const filteredItems = items.filter(item => !item.isDisabled);
|
|
const scrollViewRef = useRef();
|
|
const animationValue = useRef(new Animated.Value(0)).current;
|
|
const [isVisible, setIsVisible] = useState(false);
|
|
const {
|
|
text
|
|
} = value;
|
|
useEffect(() => {
|
|
if (!isVisible && text.length > 0) {
|
|
setIsVisible(true);
|
|
}
|
|
}, [isVisible, text]);
|
|
useLayoutEffect(() => {
|
|
onChangeOptions(items);
|
|
scrollViewRef.current?.scrollTo({
|
|
x: 0,
|
|
animated: false
|
|
});
|
|
if (isVisible && text.length > 0) {
|
|
startAnimation(true);
|
|
} else if (isVisible && text.length === 0) {
|
|
startAnimation(false);
|
|
}
|
|
// Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.
|
|
// See https://github.com/WordPress/gutenberg/pull/41820
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [items, isVisible, text]);
|
|
const activeItemStyles = usePreferredColorSchemeStyle(styles['components-autocomplete__item-active'], styles['components-autocomplete__item-active-dark']);
|
|
const iconStyles = usePreferredColorSchemeStyle(styles['components-autocomplete__icon'], styles['components-autocomplete__icon-active-dark']);
|
|
const activeIconStyles = usePreferredColorSchemeStyle(styles['components-autocomplete__icon-active '], styles['components-autocomplete__icon-active-dark']);
|
|
const textStyles = usePreferredColorSchemeStyle(styles['components-autocomplete__text'], styles['components-autocomplete__text-dark']);
|
|
const activeTextStyles = usePreferredColorSchemeStyle(styles['components-autocomplete__text-active'], styles['components-autocomplete__text-active-dark']);
|
|
const startAnimation = useCallback(show => {
|
|
Animated.timing(animationValue, {
|
|
toValue: show ? 1 : 0,
|
|
duration: show ? 200 : 100,
|
|
useNativeDriver: true
|
|
}).start(({
|
|
finished
|
|
}) => {
|
|
if (finished && !show && isVisible) {
|
|
setIsVisible(false);
|
|
reset();
|
|
}
|
|
});
|
|
},
|
|
// Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.
|
|
// See https://github.com/WordPress/gutenberg/pull/41820
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
[isVisible]);
|
|
const contentStyles = {
|
|
transform: [{
|
|
translateY: animationValue.interpolate({
|
|
inputRange: [0, 1],
|
|
outputRange: [styles['components-autocomplete'].height, 0]
|
|
})
|
|
}]
|
|
};
|
|
if (!filteredItems.length > 0 || !isVisible) {
|
|
return null;
|
|
}
|
|
return createElement(AutocompletionItemsFill, null, createElement(View, {
|
|
style: styles['components-autocomplete']
|
|
}, createElement(Animated.View, {
|
|
style: contentStyles
|
|
}, createElement(BackgroundView, null, createElement(ScrollView, {
|
|
testID: "autocompleter",
|
|
ref: scrollViewRef,
|
|
horizontal: true,
|
|
contentContainerStyle: styles['components-autocomplete__content'],
|
|
showsHorizontalScrollIndicator: false,
|
|
keyboardShouldPersistTaps: "always",
|
|
accessibilityLabel:
|
|
// translators: Slash inserter autocomplete results
|
|
__('Slash inserter results')
|
|
}, filteredItems.map((option, index) => {
|
|
const isActive = index === selectedIndex;
|
|
const itemStyle = stylesCompose(styles['components-autocomplete__item'], isActive && activeItemStyles);
|
|
const textStyle = stylesCompose(textStyles, isActive && activeTextStyles);
|
|
const iconStyle = stylesCompose(iconStyles, isActive && activeIconStyles);
|
|
const iconSource = option?.value?.icon?.src || option?.value?.icon;
|
|
return createElement(TouchableOpacity, {
|
|
activeOpacity: 0.5,
|
|
style: itemStyle,
|
|
key: index,
|
|
onPress: () => onSelect(option),
|
|
accessibilityLabel: sprintf(
|
|
// translators: %s: Block name e.g. "Image block"
|
|
__('%s block'), option?.value?.title)
|
|
}, createElement(View, {
|
|
style: styles['components-autocomplete__icon']
|
|
}, createElement(Icon, {
|
|
icon: iconSource,
|
|
size: 24,
|
|
style: iconStyle
|
|
})), createElement(Text, {
|
|
style: textStyle
|
|
}, option?.value?.title));
|
|
}))))));
|
|
}
|
|
return AutocompleterUI;
|
|
}
|
|
export default getAutoCompleterUI;
|
|
//# sourceMappingURL=autocompleter-ui.native.js.map
|