I have to use this component in my application:
const options = [
{ value: "gold" },
{ value: "lime" },
{ value: "green" },
{ value: "cyan" }
];
ReactDOM.render(
<Select
mode="multiple"
placeholder={["good"]}
style={{ width: "20%" }}
options={options}
/>,
document.getElementById("container")
);
The idea is, that i want to change it in the next way: When i will select a value from dropdown i don't want do display it in input, but i want to keep by default the text good in the input, and when i will choose an option, that option should not change the good placeholder. How to do this?
demo: https://codesandbox.io/s/custom-tag-render-ant-design-demo-j9edb?file=/index.js:149-428
EX: when will select a option from select, that option should not be displayed, and the placeholder should be in the input
Related
I have a requirement to add tooltip on hover to disabled options in a dropdown in React fluent UI.
I am able to add tooltip to singular component using https://www.npmjs.com/package/#fluentui/react-tooltip
<Tooltipcontent="Example tooltip">
<Button/>
</Tooltip>
but how to add similar behaviour to dropdown options and only for disabled options
like: "Disabled cause of non avilability"
sample dropdown fluent ui code
const options: IDropdownOption[] = [
{ key: 'fruitsHeader', text: 'Fruits', itemType: DropdownMenuItemType.Header },
{ key: 'apple', text: 'Apple' },
{ key: 'banana', text: 'Banana' },
{ key: 'orange', text: 'Orange', disabled: true },
];
export const DropdownBasicExample: React.FunctionComponent = () => {
return (
<Stack tokens={stackTokens}>
<Dropdown
placeholder="Select an option"
label="Basic uncontrolled example"
options={options}
styles={dropdownStyles}
/>
</Stack>
);
};
Thanks
Fluent UI renders every disabled option as a button element with the disabled attribute, which makes it non-interactive by default.
Here's a method to solve this that I believe is also fairly accessible:
First, define your array of IDropdownOption items so that they conditionally set the disabled and title properties:
const options: IDropdownOption[] = [
{ key: 'apple', text: 'Apple' },
{ key: 'orange',
text: 'Orange',
disabled: isOrangeDisabled,
title: isOrangeDisabled ? "This is a disabled tooltip" : ""
},
];
You're also going to need to define a custom rendering function for the items in order to apply a nice tooltip:
<Dropdown onRenderOption={onRenderOption} />
and then define a function like this in your component:
const onRenderOption = (option: IDropdownOption): JSX.Element => {
return (
<>
{option?.disabled && (
<div className="interactive">
<TooltipHost content={option.title}>
<span>{option.text}</span>
</TooltipHost>
</div>
)}
{!option?.disabled && (
<span>{option.text}</span>
)}
</>
);
};
Finally, that interactive CSS class needs to be defined in your CSS file. This will override the browser's default behaviour of making disabled elements non-interactive:
.interactive {
pointer-events: auto;
}
Some things to note:
The reason the title is set to an empty string when the option is not disabled is so that it doesn't have a string value when the interactive item is rendered. Without this, the browser will render the tooltip when you hover on a selectable item, which looks ugly.
Using the title attribute should make the component pretty usable for screen readers and other assistive technology (though I am far from an expert)
The template only renders the TooltipHost and interactive class when the object is disabled, so that the tooltip and that behaviour only kick in when the option is disabled. Because the underlying option is still disabled, you still won't be able to select it.
How to prevent opening the dropdown with suggested options when clicking on suffix component?
...
const options = [{ value: "a" }, { value: "aa" }, { value: "aaa" }];
const onClick = (e) => {
console.log("Help");
e.preventDefault();
e.stopPropagation();
};
const Suffix = <div onClick={onClick}>Help</div>;
return (
<AutoComplete
options={options}
style={{ width: 200 }}
onSelect={onSelect}
onSearch={onSearch}
onDropdownVisibleChange={(v) => console.log("onDropdownVisibleChange", v)}
>
<Input suffix={Suffix} />
</AutoComplete>
);
Use of "open" prop for controlling the dropdown state of AutoComplete component doesn't allow me to reach the goal: even though I set "open" to false into "onClick" handler, you can notice opening and closing animation of AutoComplete component when you click on "Help" ("onDropdownVisibleChange" is handled before "onClick").
I am looking for something like this to implement in ReactJS/Material-UI. Any existing component or library for this?
You can do that with the Autocomplete component by overriding the ListboxProps of the Listbox which is the container of the dropdown and set the CSS grid to display 3 equal width columns using the fr unit:
<Autocomplete
ListboxProps={{
style: {
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr",
maxHeight: "initial",
}
}}
Now assuming the option has the following type:
type TagOption = {
tag: string;
views: number;
description: string;
};
In the Stackoverflow dropdown, there are only 6 options at max, so we need to restrict the number of options shown in the Listbox:
import Autocomplete, { createFilterOptions } from "#mui/material/Autocomplete";
const _filterOptions = createFilterOptions<TagOption>();
const filterOption = (props, state) => {
const results = _filterOptions(props, state);
return results.slice(0, 6);
};
<Autocomplete filterOptions={filterOption}
We also want to create a customized option component for each grid item. Here is a minimal example without any much styles to get you started:
function OptionItem({ option, ...other }) {
return (
<li
{...other}
style={{
display: "block"
}}
>
<div>
<Chip label={option.tag} />
{option.views}
</div>
<div>{option.description}</div>
</li>
);
}
renderOption={(props, option, { selected }) => (
<OptionItem {...props} option={option} />
)}
And finally set the isOptionEqualToValue and getOptionLabel to ensure that the option get filtered properly and the input display the correct tag when selected:
isOptionEqualToValue={(option, value) => option.tag === value.tag}
getOptionLabel={(option) => option.tag}
Live Demo (Source)
That's not a perfect fit, but you can use autocomplete (using multiple, customizable and asynchronous)
I need to solve a question that is asking to change the body background colours while clicking the button I need to change four colours how I can solve it? in react.
import React, { useState } from 'react';
import './App.css';
function App() {
var colors=[
{
value:1,label:"red"
},
{
value:2,label:"green"
}
]
var [setbgcolor,ddlvalue]=useState(colors.label)
var ddlhandle=e=>{
ddlvalue(e.label)
}
return (
<div className="App">
<style>{'body {background-color:'+setbgcolor+'}'}</style>
<button onClick={ddlhandle} >click</button>
<select options={colors} onChange={ddlhandle}></select>
</div>
);
}
export default App;
You would need two states, one for holding the select's value, and other for holding current bg color. Similarly, you need two handlers, one for select and other for button. Also, you need to use option element, inside select to display the options.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
var colors = [
{
value: 1,
label: "red"
},
{
value: 2,
label: "green"
}
];
var [inputValue, setInputValue] = useState(colors[0].label);
var [bgcolor, setbgColor] = useState(colors[0].label);
var ddlhandle = (e) => {
setInputValue(e.target.value);
};
var buttonHandle = () => {
setbgColor(inputValue);
};
return (
<div
style={{ backgroundColor: bgcolor, width: "100vw", height: "100vh" }}
className="App"
>
<button onClick={buttonHandle}>click</button>
<select onChange={ddlhandle}>
{colors.map((color) => (
<option value={color.label}>{color.label}</option>
))}
</select>
</div>
);
}
CodeSandbox Link - https://codesandbox.io/s/zealous-williamson-58qf8?file=/src/App.js
Edit: Since you need to change the color of entire body, you need to set width: "100vw" and height: "100vh" of div.
you should use two className or two style for the background
and handle a parameter for change between className or style
import React, { useState } from 'react';
import './App.css';
function App() {
var colors=[
{
value:1,label:"red"
},
{
value:2,label:"green"
}
]
var [setbgcolor,ddlvalue]=useState(colors[0].label)
var ddlhandle=e=>{
ddlvalue(e.target.value)
}
return (
**<div className="App" style={{backgroundColor:`${setbgcolor}`}}>**
<button onClick={ddlhandle} >click</button>
<select options={colors} onChange={ddlhandle}></select>
</div>
);
}
export default App;
If you want with a single click of a button to cicle thru an array of possible colors to change the background color, you can simply store the array index of the current one and +1 to it until you reach the limit then reset back to 0.
Heres a short example:
Created an array with objects that represent what colors can be picked
const colors = [
{ title: "Red", color: "#de1212" },
{ title: "Blue", color: "#122dde" },
{ title: "Green", color: "#32a852" },
{ title: "Yellow", color: "#d7de12" }
];
Then created a state where you can store the index of the current selected color. NOTE giving a default index of 0
const [colorValue, setColorValue] = useState(0);
Then simply, create a simple method that onClick will execute. This method will increate the index by 1 until it reaches same number as there are objects in the array. Once reached the limit it will reset it to 0
const handleClick = () =>
setColorValue(colorValue + 1 < colors.length ? colorValue + 1 : 0);
Now in a render its up to you how you render it. I simply did this to present it
<div className="App" style={{ backgroundColor: colors[colorValue].color }}>
<h1>Selected color: {colors[colorValue].title}</h1>
<button className="btn" onClick={handleClick}>
Click to change color
</button>
</div>
Live example of this code
And if you required to do this with a select and only with a button onClick to read select value and set it as color, the situation is the same just add 1 more state where you seperatly store select value OR use a ref. The rest is the same.
Also, as a note, do not use var. Its so old. Use let, for variables that values change, and const, for variables whos value do not change.
I have a list of 3 status that should be shown as the default value but I need to remove one of those options from the dropdown. I was able to disable it using the isOptionDisabled prop but my goal is to remove.
Right now I have an object with the option
export const userStatus = [
{ label: 'Active', value: 'ACTIVE' },
{ label: 'Blocked', value: 'BLOCKED' },
{ label: 'Pending', value: 'ACTIVATION_PENDING', isDisabled: true },
];
I want to remove the pending from the dropdown but show as default value if it is the default value.
My select component looks like this
<Select
name={name}
fullWidth={fullWidth}
components={{ DropdownIndicator }}
isSearchable={false}
value={selectValue}
options={options}
classNamePrefix="styled-select"
variant={variant}
isDisabled={disabled}
hasError={hasError}
onChange={onSelectChange}
isOptionDisabled={isOptionDisabled}
/>
Can you filter the options before you send it as a prop to React-Select?