@wordpress/components
Version:
UI components for WordPress.
148 lines (136 loc) • 6.35 kB
JavaScript
import { createElement } from "@wordpress/element";
/**
* 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(_ref) {
let {
filterValue,
selectedIndex,
onChangeOptions,
onSelect,
value,
reset
} = _ref;
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(() => {
var _scrollViewRef$curren;
onChangeOptions(items);
(_scrollViewRef$curren = scrollViewRef.current) === null || _scrollViewRef$curren === void 0 ? void 0 : _scrollViewRef$curren.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(_ref2 => {
let {
finished
} = _ref2;
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) => {
var _option$value, _option$value$icon, _option$value2, _option$value3, _option$value4;
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 === null || option === void 0 ? void 0 : (_option$value = option.value) === null || _option$value === void 0 ? void 0 : (_option$value$icon = _option$value.icon) === null || _option$value$icon === void 0 ? void 0 : _option$value$icon.src) || (option === null || option === void 0 ? void 0 : (_option$value2 = option.value) === null || _option$value2 === void 0 ? void 0 : _option$value2.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 === null || option === void 0 ? void 0 : (_option$value3 = option.value) === null || _option$value3 === void 0 ? void 0 : _option$value3.title)
}, createElement(View, {
style: styles['components-autocomplete__icon']
}, createElement(Icon, {
icon: iconSource,
size: 24,
style: iconStyle
})), createElement(Text, {
style: textStyle
}, option === null || option === void 0 ? void 0 : (_option$value4 = option.value) === null || _option$value4 === void 0 ? void 0 : _option$value4.title));
}))))));
}
return AutocompleterUI;
}
export default getAutoCompleterUI;
//# sourceMappingURL=autocompleter-ui.native.js.map