What i want, a "reset/clear" button on the first page to refresh the searchable drop down list of react-select with Formik.This is the first page,the one after is the second,the problem iam facing is to refresh the code from a clear button in the first page,i tried everything i can to change,i added some props that are not needed.
<SearchableDropDownList
onChange={(value) =>
formik.setFieldValue('formDay', value || null)}
resetValue={resetValue}
value={formik.values.formDay}
options={dayOptions}
formik={formik}
/>
import React from 'react';
import Select from 'react-select';
import CreatableSelect from 'react-select/creatable';
import chroma from 'chroma-js';
import { StylesConfig } from 'react-select';
// https://codesandbox.io/s/1j4zxl8bq
export default ({ inputRef, onChange, options, value, className, resetValue, onBlur, formik }) => {
// -----------Creating design for react-select----------------------------For Creatable--umust
// --u must set this line as well : const color = chroma(data.color ?? 'black'); because there is no data on creatable
// so i must handle the empty created by the user input
const dot = (color = 'white') => ({
alignItems: 'center',
display: 'flex',
':before': {
backgroundColor: color,
borderRadius: 10,
content: '" "',
display: 'block',
marginRight: 8,
height: 10,
width: 10,
},
});
const colourStyles = {
control: (styles) => ({
...styles,
backgroundColor: '#212529',
borderRadius: 10,
borderColor: '#323232',
}),
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
const randomColor = 'black';
const color = chroma(data.color ?? 'black');
return {
...styles,
backgroundColor: isDisabled
? undefined
: isSelected
? randomColor
: isFocused
? color.alpha(0.1).css()
: undefined,
color: isDisabled
? '#ccc'
: isSelected
? chroma.contrast(color, 'white') > 2
? 'white'
: 'blue'
: randomColor,
cursor: isDisabled ? 'not-allowed' : 'default',
':active': {
...styles[':active'],
backgroundColor: !isDisabled
? isSelected
? randomColor
: color.alpha(0.3).css()
: undefined,
},
};
},
input: (styles) => ({
...styles,
...dot(),
color: 'grey',
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
placeholder: (styles) => ({
...styles,
...dot('#ccc'),
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
singleValue: (styles, { data }) => ({
...styles,
...dot('white'),
color: 'grey',
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
};
if (resetValue === true) {
value = null;
// formik.setFieldValue('formDay', null)
resetValue = false;
}
const handleChange = (event) => {
// Overwrite the event with your own object if it doesn't exist
if (!event || value === null) {
event = {
target: inputRef,
value: '',
};
}
onChange(event);
};
const defaultValue = (options, value) => {
return options ? options.find((option) => option.value === value) : null;
// return {value:'developer',label:'Software Developer'};
};
// const randomColor = `#`.concat( Math.floor(Math.random()*16777215).toString(16))
// const color = chroma.random();
// const color = chroma(data.color ?? 'black');
// https://nibes.cn/blog/22525
return (
<div className={className}>
<CreatableSelect
value={defaultValue(options, value)}
styles={colourStyles}
onChange={handleChange}
isClearable
ref={inputRef}
options={options}
/>
</div>
);
};
Related
I am using a popconfirm to show up when trying to close a modal, I want the popconfirm position to be below the X button of the modal, I have tried to move its position with the "overlaystyle" property and if I edit the values while the popconfirm is open it works, but if the screen dimensions change or the popconfirm is closed.
it returns to its original position, is there any way to make it stay below the X of the modal?
import { ExclamationCircleFilled } from "#ant-design/icons";
import { Popconfirm } from "antd";
import { useEffect, useState } from "react";
type EditModalCloseType = {
width: number
popupOpen: boolean;
onConfirm: () => void;
onCancel: () => void;
};
export const EditModalClose = ({width, popupOpen, onConfirm, onCancel }: EditModalCloseType) => {
useEffect(() => {
calculateOverlayStyle(width);
}, [width]);
const description = "¿Estás seguro de salir sin actualizar? los cambios se perderan"
const calculateOverlayStyle = (width: number) => {
setOverlayStyle({
...(width < 688 && { marginLeft: '20px', marginTop: '-160px' }),
...(width < 1300 && { position: 'absolute', top: '50%', left: '50%' }),
...(width >= 1300 && { position: 'absolute', top: '50%', left: '50%' })
});
}
const [overlayStyle, setOverlayStyle] = useState({});
return <Popconfirm
title={description}
open={popupOpen}
placement="bottom"
autoAdjustOverflow={true}
overlayStyle={overlayStyle}
icon={<ExclamationCircleFilled style={{ color: 'red' }} />}
okText="Salir"
okButtonProps={{ style: { backgroundColor: 'red', color: 'white' } }}
onConfirm={onConfirm}
cancelText="Regresar"
onCancel={onCancel}
/>
}
const PopupCancel = () => {
setPopupOpen(false);
};
const PopupConfirm = () => {
resetFields();
setPopupOpen(false);
setOpenModal(false);
}
I tried to create a function according to the width of the screen that would adjust it according to that property but the same error I mentioned in the post keeps occurring.
I can select first option successfully, but after that it doesn't display any option, can't add second option and I even added isMulti.
import React from "react";
import AsyncSelect from "react-select/async";
import makeAnimated from "react-select/animated";
import { options } from "../colorOptions";
import chroma from "chroma-js";
const animatedComponents = makeAnimated();
export const SelectBox = () => {
const loadOptions = (searchValue, callback) => {
console.log(searchValue);
setTimeout(() => {
const filteredOptions = options.filter((option) =>
option.name.toLowerCase().includes(searchValue.toLowerCase())
);
console.log(filteredOptions);
callback(filteredOptions);
}, 1000);
};
const colorStyles = {
control: (styles) => ({ ...styles, backgroundColor: "white" }),
option: (styles, { data, isDesable, isFocused, isSelected }) => {
return { ...styles, color: data.colorCode };
},
multiValue: (styles, { data }) => {
const color = chroma(data.colorCode);
return {
...styles,
backgroundColor: color.alpha(0.1).css(),
color: data.colorCode
};
},
multiValueLabel: (styles, { data }) => ({
...styles,
color: data.colorCode
})
};
return (
<AsyncSelect
key={options.length}
loadOptions={loadOptions}
option={options}
closeMenuOnSelect={false}
components={animatedComponents}
isMulti
defaultOptions
styles={colorStyles}
/>
);
};
code sandbox link:
https://codesandbox.io/s/dreamy-water-j2m55v?file=/src/components/SelectBox.jsx:0-1401
code sandbox link:
https://codesandbox.io/s/dreamy-water-j2m55v?file=/src/components/SelectBox.jsx:0-1401
my mistake
i should provide my collection of option in this format
export const options = [ { id: 1, value: "Red", colorCode: "#FF0000", label: "Red" }, ];
when i change to this format the code works
I want replace the "Cancel" Text on the Searchbar button (See a screenshot on the bottom) with an Icon (See the code on the bottom).
This it the render part with the default props:
render() {
const _a = this.props, { theme, cancelButtonProps, cancelButtonTitle, clearIcon, containerStyle, leftIconContainerStyle, rightIconContainerStyle, inputContainerStyle, inputStyle, placeholderTextColor, showLoading, loadingProps, searchIcon, showCancel } = _a, attributes = __rest(_a, ["theme", "cancelButtonProps", "cancelButtonTitle", "clearIcon", "containerStyle", "leftIconContainerStyle", "rightIconContainerStyle", "inputContainerStyle", "inputStyle", "placeholderTextColor", "showLoading", "loadingProps", "searchIcon", "showCancel"]);
const { hasFocus, isEmpty } = this.state;
const { style: loadingStyle } = loadingProps, otherLoadingProps = __rest(loadingProps, ["style"]);
const { buttonStyle, buttonTextStyle, color: buttonColor, disabled: buttonDisabled, buttonDisabledStyle, buttonDisabledTextStyle } = cancelButtonProps, otherCancelButtonProps = __rest(cancelButtonProps, ["buttonStyle", "buttonTextStyle", "color", "disabled", "buttonDisabledStyle", "buttonDisabledTextStyle"]);
return (<View style={StyleSheet.flatten([
styles.container,
{ backgroundColor: theme.colors.white },
containerStyle,
])}>
<Input testID="searchInput" renderErrorMessage={false} {...attributes} onFocus={this.onFocus} onBlur={this.onBlur} onChangeText={this.onChangeText} ref={(input) => {
this.input = input;
}} inputStyle={StyleSheet.flatten([styles.input, inputStyle])} containerStyle={{
paddingHorizontal: 0,
}} inputContainerStyle={StyleSheet.flatten([
styles.inputContainer,
{ backgroundColor: theme.colors.platform.ios.searchBg },
hasFocus && { marginRight: this.state.cancelButtonWidth },
inputContainerStyle,
])} leftIcon={renderNode(Icon, searchIcon, defaultSearchIcon(theme))} leftIconContainerStyle={StyleSheet.flatten([
styles.leftIconContainerStyle,
leftIconContainerStyle,
])} placeholderTextColor={placeholderTextColor || theme.colors.platform.ios.grey} rightIcon={<View style={{ flexDirection: 'row' }}>
{showLoading && (<ActivityIndicator key="loading" style={StyleSheet.flatten([{ marginRight: 5 }, loadingStyle])} {...otherLoadingProps}/>)}
{!isEmpty &&
renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))}
</View>} rightIconContainerStyle={StyleSheet.flatten([
styles.rightIconContainerStyle,
rightIconContainerStyle,
])}/>
<View style={StyleSheet.flatten([
styles.cancelButtonContainer,
{
opacity: this.state.cancelButtonWidth === null ? 0 : 1,
right: hasFocus ? 0 : -this.state.cancelButtonWidth,
},
])} onLayout={(event) => this.setState({ cancelButtonWidth: event.nativeEvent.layout.width })}>
<TouchableOpacity accessibilityRole="button" onPress={this.cancel} disabled={buttonDisabled} {...otherCancelButtonProps}>
<View style={[buttonStyle, buttonDisabled && buttonDisabledStyle]}>
<Text style={[
styles.buttonTextStyle,
buttonColor && { color: buttonColor },
buttonTextStyle,
buttonDisabled &&
(buttonDisabledTextStyle || styles.buttonTextDisabled),
]}>
{cancelButtonTitle}
</Text>
</View>
</TouchableOpacity>
</View>
</View>);
}
}
SearchBar.defaultProps = {
value: '',
cancelButtonTitle: 'Cancel',
loadingProps: {},
cancelButtonProps: {},
showLoading: false,
onClear: () => null,
onCancel: () => null,
onFocus: () => null,
onBlur: () => null,
onChangeText: () => null,
searchIcon: { name: 'ios-search' },
clearIcon: { name: 'ios-close-circle' },
showCancel: false,
};
Its looking like this:
Now I want to replace this "Cancel" with an Icon:
const defaultCancelIcon = (theme) => ({
type: 'material',
size: 25,
color: theme?.colors?.platform?.android?.grey,
name: 'arrow-back',
});
Since I havent worked with edited react-native-elements yet, I dont dont really know how to do this. I tried to change the defaultProps, but it didnt change anything. How can I do this?
type
<YourIconName />
instead of 'cancel', like
SearchBar.defaultProps = {
value: '',
cancelButtonTitle: <YourIconName />,
loadingProps: {},
...
};
I think it should work
I am trying to achieve to prevent the enter key selection while user has nothing typed and press the enter key. In current situation when user click on react-select and hit the enter key then its selecting the first value from the drop down, where user has nothing typed but still its selection first value from drop down. Is anyone has any idea to prevent this functionality.
It should only select when user type something in input box and select or hit enter key.
here is the screen short where user has nothing typed and press enter key then its selecting first value.
here is code:
import React from 'react';
import Select from 'react-select';
class CreateSelectOption extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: this.props.options,
questionsCount: props.questionsCount,
inputValue: '',
}
this.processQuestions = this.processQuestions.bind(this);
}
componentWillReceiveProps(newProps) {
if (newProps.questionsCount.length > 0) {
this.setState({
questionsCount: newProps.questionsCount
})
}
}
onChange = (e, props) =>{
this.props.onChange(e, props.technology, props.id, props.type, props.noc, props.dataTech, props.dataType);
}
onInputValueChange = inputValue => {
this.setState({ inputValue: this.allowOnlyOneSpace(inputValue) });
};
allowOnlyOneSpace = str => {
return str.endsWith(" ") ? str.trim() + " " : str.trim();
};
render() {
const customStyles = {
control: (styles, state) => ({
...styles,
borderRadius: '1px', // default border color
boxShadow: 'none', // no box-shadow
color: '#007bff',
height: '27px',
minHeight: '30px'
}),
singleValue: (styles, state) => ({
...styles,
color: '#007bff',
top: '42%'
}),
dropdownIndicator: (styles, state) => ({
...styles,
padding: "6px"
}),
menuPortal: base => ({ ...base, zIndex: 9999, fontSize: '12px' })
}
const { selectedTech }=this.props;
const selectedVal = selectedTech ? { value: selectedTech , label: selectedTech } : null;
return(
<Select
className="select-width select-color"
menuPortalTarget={document.body}
styles={customStyles}
value={selectedVal}
onChange={(e) => { this.onChange(e, this.props) }}
options={props.technologyArray && props.technologyArray.map(t => ({ value: t, label: t }))}
openMenuOnClick={true}
placeholder="Please select tech"
components={{ IndicatorSeparator: () => null }}
inputValue={this.state.inputValue}
onInputChange={this.onInputValueChange}
disabled={this.state.inputValue.length === 0}
/>
)
}
}
export default CreateSelectOption;
UPD options={this.state.inputValue.length === 0 ? [] : colourOptions}
try these properties
openMenuOnFocus={false}
openMenuOnClick={false}
and I guess (can't check that right now though) that also this is working too (if selectedVal is present, then it turns to true else false)
openMenuOnFocus={selectedVal}
openMenuOnClick={selectedVal}
Trying to set the colors based on props for an inner selector ('&$selected' and '&:hover'). But the colors are not applied, though I can see the class related to selected being applied.
const getColor = (color, theme) => {
return color === 'primary'
? theme.palette.primary.contrastText
: color === 'secondary'
? theme.palette.secondary.contrastText
: theme.palette.action.active;
};
const getBgColor = (color, theme) => {
return color === 'primary'
? theme.palette.primary.main
: color === 'secondary'
? theme.palette.secondary.main
: theme.palette.action.active;
};
const useStyles = makeStyles(theme => ({
root: {
textTransform: 'none',
// This does not apply the set colors
'&$selected': {
color: ({ color }) => getColor(color, theme),
backgroundColor: ({ color }) =>
getBgColor(color, theme),
// This is not applied as well
'&:hover': {
backgroundColor: ({ color }) =>
getBgColor(color, theme),
},
},
},
selected: {},
}))