changing checkbox background color width styled components - reactjs

I want to control the background color of checkbox but something is wrong.
first,
I have a data like
export const data = [
{id: 1, checked: true},
{id: 2, checked: false},
{id: 3, checked: false},
]
and a component got this data is like
import {data} from "./data"
(...)
{data.map(item => <label key={item.id}> <input type="checkbox" checked={item.checked}/> </label>}
when i was trying to change the background color of label,
i wrote code like this...
background: ${props => props.checked ? "#000" : "transparent"};
but this doesn't work well. the label has background color transparent only. how can i handle this??

in this case you could just use add style={{background: item.checked ? "#000" : 'transparent'}} to your label.
props refers to the values passed into a react component, in this case we're just using a regular label.
FYI - since you're hard-coding your data, your checkboxes won't be changeable - if thats something you need, you'll probably want to look at saving your data as a state, then modifying that based on the checkboxes being checked/unchecked.
const data = [
{id: 1, checked: false},
{id: 2, checked: true},
{id: 3, checked: false},
]
const element = (
<div>
{data.map( item => (
<label
key={item.id}
style={{background: item.checked ? "#000" : 'transparent'}}
>
<input type="checkbox" checked={item.checked} />
</label>
))}
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);

Related

React Fluent UI dropdown disabled tooltip on hover

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.

Material UI dropdown is uncontrolled

I am new to Material UI and have an issue. I have a reusable dropdown filter that is populated from an array. Everything works exactly how I want it to, but I keep getting a console error that the component is changing and uncontrolled input. The problem is, if I add a default value (value='') to eliminate the uncontrolled error, the dropdown will not display my selected filtering option in the input, just a blank. How can I control the component but still show my the user the filtering option selected.
const status = [
{id: 1, label: '...', value: ''},
{id: 2, label: 'Active', value: 48},
{id: 3, label: 'Inactive', value: -1},
{id: 4, label: 'On Hold', value: 48654},
{id: 5, label: 'Out Of Spec', value: 50989},
]
<DropdownFltr
prompt='Status...'
options={status}
onChange={handleFilterValue}
/>
export default function DropdownFltr(props) {
const { error=null, options, prompt, onChange, value, ...other } = props;
return(
<>
<FormControl>
<InputLabel>{prompt}</InputLabel>
<Select
value='' // <<< Causes issues, but fixed uncontrolled error
onChange={onChange}
{...other}
{...(error && {error:true, helperText:error})}
>
{options.map((option, id) => (
<MenuItem
key={option.id}
value={option.value}
>
{option.label}
</MenuItem>
))}
</Select>
</FormControl>
</>
)
}
Add the default Value in the Component Select
<Select
defaultValue={''}
/>

How to create a typeahead menu in React and populate it with options from an Postgresql table?

I'm using React, Node, Express, Postgresql for a simple project. The dropdown menu should have it's select options populated from a postgresql table.
id
name
1
sam
2
frank
3
joe
4
sally
I have tried creating a typeahead menu based on the plugin below:
https://github.com/ericgio/react-bootstrap-typeahead
Below is the typeahead code I tried using
<Fragment>
<Form.Group>
<Form.Label>Single Selection</Form.Label>
<Typeahead
id="basic-typeahead-single"
labelKey="name"
onChange={setSingleSelections}
options={options}
placeholder="Choose a state..."
selected={singleSelections}
/>
</Form.Group>
</Fragment>
Just running that alone gave me some errors, so I changed it up like so:
<div className="form-group">
<div className="form-label">Single Selection</div>
<Typeahead
id="basic-typeahead-single"
labelKey="name"
onChange={setSingleSelections}
options={options}
placeholder="Choose a state..."
selected={singleSelections}
/>
</div>
This is where I'm stuck as I'm not sure how to modify the code to populate the options with column name from the table above. In the past I had trouble using datalist as there was no way to limit the display results, so my dropdown menu would extend past the app screen. Honestly any and all help is appreciated, thanks!
You need to define your options as an array of objects and pass them as a prop to Typeahead.
const MyComponent = (props) => {
const [singleSelections, setSingleSelections] = useState([]);
const options = [
{ id: 1, name: "sam" },
{ id: 2, name: "frank" },
{ id: 3, name: "joe" },
{ id: 4, name: "sally" },
];
return (
<div className="form-group">
<div className="form-label">Single Selection</div>
<Typeahead
id="basic-typeahead-single"
labelKey="name"
onChange={setSingleSelections}
options={options}
placeholder="Choose a person..."
selected={singleSelections}
/>
</div>
);
};
I'm not familiar with this API, but it appears that you can customize how the options are rendered in the menu according to these docs.

Remove or hide option from react-select dropdown

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?

react-rte (Rich Text Editor): how to implement inline style for custom components?

react-rte is a Rich Text Editor based on draft-js. My goal is to customize the toolbar components with, e.g., material ui react components. Reading through the react-rte docs, I think that there are two styling hooks:
toolbarConfig for CSS (link); and
customControls for completely overriding components (as seen in demo).
I believe that my use case calls for customControls, but from the provided demo (see below) I am not able to understand how to hook the custom components back into rte's functionality. For example, if I render a custom button component for BOLD, how does this button get the default functionality that would have gone to the default button provided by toolbarConfig?
editor demo with customControls:
<RichTextEditor
value={value}
onChange={this._onChange}
className="react-rte-demo"
placeholder="Tell a story"
toolbarClassName="demo-toolbar"
editorClassName="demo-editor"
readOnly={this.state.readOnly}
customControls={[
// eslint-disable-next-line no-unused-vars
(setValue, getValue, editorState) => {
let choices = new Map([
['1', {label: '1'}],
['2', {label: '2'}],
['3', {label: '3'}],
]);
return (
<ButtonGroup key={1}>
<Dropdown
choices={choices}
selectedKey={getValue('my-control-name')}
onChange={(value) => setValue('my-control-name', value)}
/>
</ButtonGroup>
);
},
<ButtonGroup key={2}>
<IconButton
label="Remove Link"
iconName="remove-link"
focusOnClick={false}
onClick={() => console.log('You pressed a button')}
/>
</ButtonGroup>,
]}
/>
my currently invalid implementation:
<RichTextEditor
value={this.state.value}
onChange={this.onChange}
customControls={rteCustomControls}
/>
...
const inlineStyleButtonControls = [
{ label: "format_bold", style: "BOLD", component: FormatBoldIcon },
{ label: "format_italic", style: "ITALIC", component: FormatItalicIcon },
{
label: "format_underlined",
style: "UNDERLINE",
component: FormatUnderlinedIcon,
},
];
const rteCustomControls = [
(setValue, getValue, editorState) => {
return inlineStyleButtonControls.map((button, i) => (
<IconButton
key={i}
color="inherit"
aria-label={button.label}
selectedKey={getValue(button.style)}
onClick={value => setValue(button.style, value)}
>
<button.component />
</IconButton>
));
},
];
If your goal is purely to modify the display, you should be able to target the buttons via CSS to change their displays, just like you would target any other DOM element.
Change element display via CSS.
RichTextEditor button:nth-child(1){
background-image: url('/icon1.svg');
}
RichTextEditor button:nth-child(2){
background-image: url('/icon2.svg');
}
Or, change element display via javascript
Array.from(document.querySelectorsAll('RichTextEditor button')).forEach((el)=>{
// Modify element here
})
If you also want to modify the button's functionality, you can look at the code where they are defined, and potentially add them in as custom controls.

Resources