How to change the style of a Ant-Design 'Select' component? - css

Suppose I want to change the standard white background color of the Select component to green.
My try...
<Select
style={{ backgroundColor: 'green' }}>
// Options...
</Select>
...didn't do it.
Can someone point me in the right direction?
[EDIT]
I ended up using the suggested approach from Jesper We.
Overwriting the color for all selections...
.ant-select-selection {
background-color: transparent;
}
...then I could style the Select components individually.

<Select> renders a whole set of <div>s, you need to take a look at the resulting HTML element tree to understand what you are doing. You can't do it through the style attribute, you need to do it in CSS.
The proper place to attach a background color is
.ant-select-selection {
background-color: green;
}
This will make all your selects green. Give them individual classNames if you want different colors for different selects.

For my form with Select element a have some code in render:
const stateTasksOptions =
this.tasksStore.filters.init.state.map(item =>
<Select.Option key={item.id} value={item.id} title={<span className={`${item.id}Label`}>{item.title}</span>}>
<span className={`${item.id}Label`}>{item.title}</span> - <span class="normal-text">{item.help}</span>
</Select.Option>
)
return (
....
<Select
mode="multiple"
value={this.tasksStore.filters.selected.state.map(d => d)}
onChange={this.handleTasksStatus}
optionLabelProp="title"
>
{stateTasksOptions}
</Select>
....
)
And some css for colorizing.
Result:

Try dropdownStyle instead of style.
<Select
dropdownStyle={{ backgroundColor: 'green' }}>
// Options...
</Select>
dropdownStyle is one of select props.
reference: antd select

From their official docs https://pro.ant.design/docs/style
Override the component style
Because of the special needs of the project, we often meet the need to cover the component style, here is a simple example.
Antd Select In multi-select state, the default will show all the select items, here we add a limit height for display scroll bar when the content beyond this height.
// TestPage.ts
import { Select } from 'antd';
import styles from './TestPage.less';
const Option = Select.Option;
const children = [];
for (let i = 10; i < 36; i++) {
children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
}
ReactDOM.render(
<Select
mode="multiple"
style={{ width: 300 }}
placeholder="Please select"
className={styles.customSelect}
>
{children}
</Select>,
mountNode,
);
/* TestPage.less */
.customSelect {
:global {
.ant-select-selection {
max-height: 51px;
overflow: auto;
}
}
}
Two points need to be noted:
The imported antd component class name is not translated by CSS Modules, so the overridden class name .ant-select-selection must be put in :global.
Because of the previous note, the override is global. To avoid affecting other Select components, the setting needs to be wrapped by an extra classname to add range restriction

with all the above answers you cant change the styles of tags conditionally but with below approach you can.
You can do a hack and change the styles as you like of tags of select dropdown.
You can use dropdownRender of select which takes 2 arguments
menuNode
props
use props children property to reach to each tag and change the styles and you can conditionally change the styles as you like.
for reference below is the example link for code sandbox
Select Tags Styles Sanbox
May not be an efficient way to do it but you can use this for now to meet your business requirement.
Thanks

Somebody stated the selector to be
.ant-select-selection {...
However it should be selector as follows:
.ant-select-selector {
background-color: green;
}

They implemented this feature with v4 of ant design:
https://github.com/ant-design/ant-design/pull/21064
But beware before blindly upgrading from v3 -> v4 - a lot has changed:
https://github.com/ant-design/ant-design/issues/20661

menuItemSelectedIcon={(props) => {
return (mode == "multiple" ?
<Tooltip title="Check to confirm the apps alongwith the vendor">
<input type="checkbox" checked={props.isSelected}
style={{
margin: 5
}}
/>
</Tooltip>
: null)
}}

Lastly I was working on ant dropdown and it did not get style as I wanted and I did not find a good solution for that.
Then I decided to share my css solution for those who are in my situation:
.license-plate-letters {
overflow-y: hidden !important;
min-width: 240px !important;
.rc-virtual-list-holder>div {
height: auto !important;
}
.rc-virtual-list-holder-inner {
display: grid !important;
grid-template-columns: repeat(5, 1fr) !important;
flex-direction: row !important;
flex-wrap: wrap !important;
.ant-select-item-option {
padding: 0.5rem 12px !important;
&:hover {
background-color: #452380d2 !important;
color: white !important;
}
}
}
}
<Select
virtual={false}
popupClassName="license-plate-letters">
<Select.Option key={sth} Title="title">title</Select.Option>
</Select>

In angular, you can override the style with ng-deep
::ng-deep .ant-select-selector {
background-color: red;
}

Related

Change body background with data-theme attribute on click with React

I'm trying to change the theme in an app using the data attribute and then changing the CSS variables according to the different data-theme values.
In the App component, I check if the user has a default theme set, and use that to set new theme on click
import "./styles.css";
import useLocalStorage from "use-local-storage";
export default function App() {
// Check user set theme mode...
const defaultDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
// Create theme mode state...
const [theme, setTheme] = useLocalStorage(
"theme",
defaultDark ? "dark" : "light"
);
// Handle on click from the theme switcher...
const clickHandler = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
};
return (
<div className="App" data-theme={theme}>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={() => clickHandler()}>Dark Mode</button>
</div>
);
}
In the styles.css I set the different variables to define the theme
/* Set the dark mode variables... */
[data-theme="dark"] {
--background: black;
--title-text: white;
--desc-text: grey;
}
/* Set the light mode variables... */
[data-theme="light"] {
--background: white;
--title-text: black;
--desc-text: grey;
}
/* Page Styles... */
body {
padding: 0;
margin: 0;
background: var(--background);
}
/*The rest of the CSS...*/
The rest of the elements work fine as they are wrapped in an element that has the data-theme attribute. However, the body is not wrapped with the data-theme attribute, so there is no change in the body background. In this example, I used .App but I would like to change the body instead. Is there a way to wrap the body in the data-theme attribute in React?
Here is the link to the full code in CodeSandbox
Full code on CodeSandbox
How about wrap App with div.body them pass data-theme into .body instead and make div.body cover body
<div className='body' data-theme={theme}>
<div className='App'></div>
</div>

React jsx conditional styling of <input/> component

I am conditionally styling my <input/> (standard HTML) component. I am passing inline JSX style as a style prop:
render() {
return (
<>
<input
type="text"
style={{
width: "100%",
paddingLeft: "8px",
paddingTop: "6px",
paddingBottom: "6px",
border: this.state.error
? "2px solid red"
: this.state.value
? "2px solid #2684ff"
: "2px solid hsl(0, 0%, 80%)",
outline: "0px",
"&:hover": {
border: "2px solid green"
}
}}
placeholder={this.props.placeholder}
onChange={this.handleInput}
onFocus={this.checkErrors}
value={this.state.value}
onBlur={this.sendData}
/>
{this.state.error ? (
<div className="errorMsg"> {this.props.errorMsg} </div>
) : null}
</>
);
}
My conditional styles work, and <input/> border colour changes based on this.state.error and this.state.value, however I can't get '&:hover' style to work. I have checked my .css and there is nothing overriding the style passed as props.
I have tried another approach, where I conditionally set className for my <input/> and define style in external .css file. It works and I can change border colour with:
input[type="text"]:hover {
border: 2px solid pink;
}
However, I would like to make this work in inline JSX. Why does my style for '&:hover': { ... } not work?
The "&" operator mean the current selector in preprocessing language like sass:
input {
&:hover {
background: red;
}
}
Will compile to:
input:hover {
background: red;
}
But you will have to use sass or styled component to use that sync tax.
Pseudo css selectors don't work in inline style.btw I would not recommend any of the js solution in the comments above .you need a more a robust css solution to handle all kind of pseudo selectors.
Your options are:
Use css in js solution like styled-components.https://styled-components.com/
Use regular css or scss and condionaly switch classNames.You
can utilize classnames library for easier experience.https://www.npmjs.com/package/classnames
Render style tag above your input and put your input styles there.quite bad practice and ugly.

StencilJS | Use CSS "+ Selector " in component

I am working on a web component library with StencilJS, and I have a problem using the CSS + Selector. I have a Breadcrumb web component, which will contain multiple breadcrumb items (web component as well). Every Breadcrumb item after the first item should add > smybol with ::before. Therefore I use the CSS + selector
df-breadcrumb.tsx
export class DFBreadcrumb {
render() {
return <ol class="breadcrumb">
<slot></slot>
</ol>
;
}
}
df-breadcrumb-item.tsx
export class DFBreadcrumbItem {
/**
* Link
*/
#Prop() link: string;
render() {
return this.link ? <li class="breadcrumb-item"><a href={this.link}><slot></slot></a></li> :
<li class="breadcrumb-item"><slot></slot></li>
;
}
}
test.html
<df-breadcrumb>
<df-breadcrumb-item link="#">Start</df-breadcrumb-item>
<df-breadcrumb-item link="#">Library</df-breadcrumb-item>
<df-breadcrumb-item>Item</df-breadcrumb-item>
</df-breadcrumb>
my css rule
.breadcrumb-item+.breadcrumb-item:before {
display: inline-block;
padding-right: .5rem;
color: #6c757d;
content: ">";
}
expected output: Start > Library > Item
current output: Start Library Item
I think this is not working cause Stencil ecapsulates my li tags and their direct parent is not the ol. I read something about using the :host() pseudo class, but could not got it working. Also I have set shadow: falsein my components.
You're right, the problem is the df-breadcrumb-item element.
A simple alternative would be to apply your CSS to the df-breadcrumb-item elements:
df-breadcrumb-item + df-breadcrumb-item:before {
display: inline-block;
color: #6c757d;
content: ">";
}
Alternatively you could add the arrow to the .breadcrumb-item element inside the df-breadcrumb-item component, either depending on a property or by manually checking if the #Element() is the last node.

Is there a way to apply css style to a disabled ion-select-option

I have a list of statuses , i want the user to select one , not all statuses are enabled some of them will be disabled .
I want the disabled options to have some css styling (like gray color)
<ion-select [(ngModel)]="selectedStatus">
<ion-select-option [disabled]="isStatusDisabled(o)" *ngFor="let o of appointmentStatusOptions" [value]="o">
{{appointmentStatus[o]}}</ion-select-option>
</ion-select>
i have tired to select the element by :disabled like:
ion-select-option[disabled] {
--color:gray;
}
and tried to change all disabled as disperate action like :
:disabled {
--color:gray;
}
the css style doesn't appear at the borwser at all
ionic adds class .select-disabled for the disabled select so you can try to specify that in your css
To change globally you can add this in component style sheet:
::shadow /deep/ button[disabled] .alert-radio-label {
color: gray;
}
Or on global.scss:
ion-alert button[disabled] .alert-radio-label {
color: gray;
// color: var(--ion-color-gray, gray);
}

How do you add multiple browser specific values into a CSS style in React?

This is mainly to define browser specific values like this one for a given CSS property:
<div style="cursor: -moz-grab; cursor: -webkit-grab; cursor: grab;">Grab me!</div>
If I wrap it into object like this:
<div style={{
cursor: "-moz-grab",
cursor: "-webkit-grab",
cursor: "grab"
}}>Grab me!</div>
then you duplicate keys in an object (would fail in strict mode and would overwrite otherwise). And simply putting all values into single string doesn't seem to work either.
Figuring out browser with JS and then applying right value seems to be too much work.. Or is there a different approach to do this? Any ideas?
If you want to use inline styles and also get vendor prefixing, you can use a library like Radium to abstract the vendor prefixing for you.
By adding a #Radium decorator to your component, Radium will hook into the styles you pass to the component and automatically manage and prefix them.
var Radium = require('radium');
var React = require('react');
#Radium
class Grabby extends React.Component {
render() {
return (
<div style={style}>
{this.props.children}
</div>
);
}
}
var style = {
cursor: "grab" // this will get autoprefixed for you!
};
The best you could do is to create a css class with the cursor attribute, and add it to your component
.container {
height: 10px;
width: 10px;
}
.grab {
cursor: -moz-grab,
cursor: -webkit-grab,
cursor: grab,
}
Then in your react component:
var isGrabEnabled = true;
<div className={['container', (isGrabEnabled ? 'grab' : '')]}>Grab me!</div>

Resources