How to customize react-select component? - css

I have a little problem with react-select component restyling. If you take a look on their official doc you'll see all the attributes that can be restyled. The problem I have is that around the text I write there's blue borders, and can't remove them. Also around the container.
If I inspect it here's what I get:
It has as id react-select-3-input and can't remove that even if I write directly on chrome inspection let alone doing it in the code.
I am using nextjs as framework and I added a file style.css and import it into _app.tsx. I tried adding this to see what happens:
#react-select-2-input {
background-color: red;
color: red;
font-size: 40;
background-color: red;
}
But nothing happens.
How do you think I can fix this?

If you read the documentation for react-select you can see that the docs steer you towards using emotion more than straight forward CSS.
When implementing this you work should do something like this:
const reactSelectStyles = {
singleValue: (provided, state) => ({
...provided,
color: 'inherit',
}),
menu: (provided, state) => ({
...provided,
'z-index': 9,
}),
multiValue: (provided, state) => ({
...provided,
color: state.isDisabled ? "#000" : "#fff",
}),
};
This will create an object that you then can use for styling
<Select
styles={reactSelectStyles}
/>
Provided in the code above makes sure that the default styling is included (so you can omit it if you want to) and the state can be used to do render different styles depending on the state of the react-select.
I would say that you overall will have a harder time solving this using regular CSS since react-select (using emotion) will generate dynamic CSS classes that does not collide with each other.

Related

Ionic 6 styling of ion-datetime

I have stumbled upon some difficulties styling ion-datetime component using ionic 6, and none of the posts seem to contain a solution for this. I would like to apply some custom styles to picker items that appear in the shadow-root part.
Applying CSS to classes like .picker-item and .picker-item-active doesn't do anything because they are in the shadow-root. And there don't seem to be any styling properties and variables for ion-picker that I could use.
I am using the standard ion-datetime component like this:
<ion-datetime presentation="time"></ion-datetime>
and in the simulator while inspecting the HTML it appears as:
Styling that I would like to change:
Color and font properties for picker items
Color, background and font properties for active picker item
Since they are all open shadowRoots, you can get in and inject a <style> sheet:
document.querySelector("ion-datetime")
.shadowRoot.querySelector("ion-picker-internal")
.shadowRoot.querySelector("ion-picker-column-internal")
.shadowRoot.prepend( Object.assign( document.createElement("style") , {
innerText : `
.picker-item {
background:hotpink
}
`
}));
After some more playing around, I have been able to find a solution and customize it to my project needs. Thanks to Danny '365CSI' Engelman for inspiration.
The use of ion-datetime and its customization in my project is complex due to using multiple ion-datetime elements appearing and disappearing dynamically. Therefore, applying custom styling of it required some additional logic not posted here. Please reach out if you need some help regarding this.
Here is the base logic that allowed me to apply some styles to ion-datetime:
document.querySelectorAll("ion-datetime").forEach(dt => {
var el = dt.shadowRoot.querySelector("ion-picker-internal");
el.shadowRoot.prepend(Object.assign(document.createElement("style"), {
innerText: `
.picker-highlight {
background: red !important;
}
`
}));
el.querySelectorAll("ion-picker-column-internal").forEach(col => {
col.shadowRoot.prepend(Object.assign(document.createElement("style"), {
innerText: `
.picker-item {
color: green !important;
}
.picker-item-active {
color: blue !important;
}
`
}));
});
});

Styled Component: hover style passed in props

I have a StyledButton, and I use it like this:
const StyledButton = styled.div<{
hoverStyle?: CSSProperties
}>`
color: black;
background: blue;
// What can I do here to apply the hoverStyle?
`
<StyledButton
hoverStyle={{
backgroundColor: 'red',
color: 'white',
}}
>
My button
</StyledButton>
Are there any ways to do that?
Usually we provide individual values in extra styling props, but it is still definitely possible to provide a set of CSS rules (a CSSObject).
First you need to use an interpolation function to adapt the style based on runtime props:
const StyledButton = styled.div<{
hoverStyle?: CSSProperties
}>`
color: black;
background: blue;
// What can I do here to apply the hoverStyle?
${(props) => props.hoverStyle && inlineRules(props.hoverStyle)}
`
Here I used an inlineRules function to convert the CSSObject into a list of rules:
function inlineRules(rulesObj: CSSProperties) {
return Object.entries(rulesObj).map(([property, value]) => `${property}: ${value};`).join('');
}
Then, based on the "hoverStyle" name of your styling prop, it sounds like these rules should be applied only on :hover, rather than being directly merged with the root styles of your <div>. In that case, you need to place them in a nested block, for which you can use the & ampersand keyword to refer to the self style:
& a single ampersand refers to all instances of the component; it is used for applying broad overrides
&:hover {
${(props) => props.hoverStyle && inlineRules(props.hoverStyle)}
}
Live demo on CodeSandbox: https://codesandbox.io/s/sleepy-brook-h515v7?file=/src/App.tsx
Note: CSS rules in styled-components actually use the normal "kebab-case" notation, whereas CSSProperties are defined in camelCase ("background-color" v.s. "backgroundColor" in your example). In the above demo, I used a template literal conversion type to convert them into kebab-case, based on TypeScript add kebab case types form actual camel case keys

How to style a component "from the outside" with scoped css

I'm using scoped CSS with https://github.com/gaoxiaoliangz/react-scoped-css and am trying to follow the following rules (besides others):
Scoped component CSS should only include styles that manipulate the "inside" of the component. E.g. manipulating padding, background-color etc. is fine whilst I try to stay away from manipulating stuff like margin, width, flex etc. from within the component CSS
Manipulating the "outside" of a component (margin, width, flex etc.) should only be done by "consuming" or parent components
This is rule is somewhat derived from some of the ideas behind BEM (and probably other CSS methodologies as well) and allows for a rather modular system where components can be used without "touching their outside" but letting the parent decide how their internal layouts etc. works.
Whilst this is all fine in theory, I don't really know how to best manipulate the "outside styles" of a component from the consuming code which is best shown with an example:
search-field.scoped.css (the component)
.input-field {
background: lightcoral;
}
search-field.tsx (the component)
import './search-field.scoped.css';
type SearchFieldProps = {
className: string;
};
export const SearchField = (props: SearchFieldProps) => {
return <input className={`input-field ${props.className}`} placeholder="Search text" />;
};
sidebar.scoped.css (the consumer)
.sidebar-search-field {
margin: 16px;
}
sidebar.tsx (the consumer)
import './sidebar.scoped.css';
// ...
export const Sidebar = () => {
return (
<SearchField className="sidebar-search-field" />
(/* ... */)
);
};
In the above example, the CSS from the class sidebar-search-field in sidebar.scoped.css is not applied because the class passed to SearchField is scoped to the Sidebar and the final selector .sidebar-search-field[data-sidebarhash] simply doesn't match as the input element of the SearchField (obviously) doesn't have the data attribute data-sidebarhash but data-searchfieldhash.
ATM, I tend to create wrapper elements in situations like this which works but is rather cumbersome & clutters the markdown unnecessarily:
// ...
export const Sidebar = () => {
return (
<div className="sidebar-search-field">
<SearchField />
</div>
(/* ... */)
);
};
Question
Is there any way to "style scoped CSS component from the outside"?
Ps.: I'm not sure if all the above also applies to scoped styles in Vue. If not, please let me know how it works there so that I can create a feature request in https://github.com/gaoxiaoliangz/react-scoped-css.

angular testbed, query by css, find the pseudo element

I am writhing Angular 2+ unit test with TestBed.
Scenario, I want to verify my component, that the color of a pseudo element.
component.ts
label::before {
right: 0;
background-color: red;
}
#Component({
selector: 'app-test',
template: `
<div><label>a label</label></div>
`,
styleUrls: ['./test.component.scss'],
})
export class TestComponent {
}
so when I write unit test, I want to verify the pseudo element background color
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should set background color', () => {
const ele = fixture.debugElement.query(By.css('label::before')).nativeElement; // error here
// not sure how to use by.css to locate on the pseudo element
expect(ele.backgroundColor).toBe('....');
});
I would suggest writing your test in a different manner.
Fixture is of type ComponentFixture<T> where T is the component you are trying to access. The debugElement property has two properties that you are normally interested In when writing a test componentInstance and nativeElement
ComponentInstance is your component ts file. It's your class declaration in a sense.
NativeElement as the name suggests is the mark-up or your template
I don't think it's possible to do it the way you suggested.
However you could try
const color = window.getComputedStyle(fixture.debugElement.nativeElement.querySelector('label'), ':after').getPropertyValue('background-color');
This will give you a rgb result so for red it would be rgb(255,0,0)
I got this from: How to get pseudo element?
Try this and see if it works. It's not great that we had to access the window element inside of our test but it might solve your issue. Possibly create a better test without having to access the window api i would suggest.

What is the equivalent in CSS of the SASS/SCSS expression "&$"?

Hello I am trying to understand how a material-ui component works, and I come across the following styling:
root: (0, _extends3.default)({}, theme.typography.subheading, {
height: theme.spacing.unit * 3,
boxSizing: 'content-box',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
'&:hover': {
backgroundColor: theme.palette.text.lightDivider
},
'&$selected': {
backgroundColor: theme.palette.text.divider
}
}),
selected: {}
}
I want to know what the '&$selected' would mean in CSS syntax.
The issue I come across is that I want to overwrite the background-color passing the styling through to selected, but it is not overwriting it. I want to understand what is happening behind the scenes here.
Thanks!!!
There is no equivalent for the expression &$selected in css. &$ Is not a special symbol in both of the languages.
&$selected in scss combine from 2 parts:
&: sccc- right after the parent selector insert new sub-selectors. eample:
scss:
main-selector {
color: blue;
&.sub-selector {
display: block;
}
}
equivalent css:
main-selector {
color: blue;
}
main-selector.sub-selector {
display: block;
}
As you can see, the & symbol doesn't exist at all in css, and only apears in scss code.
$selected - this means a variable in scss. In the css code you will not be able to know if there was using in variables in the source scss file.
this variable can represent every thing in css- including selectors' names, specific colors, arrays of values, indexes, counter etc.
I can't tell you what does this variable represent in your code according to the code that you published, even that I know that it is in use, the only thing that I know about it's value in your case, is that it include a selector (And I don't know which one).
It is important you to understand, that most of the new symbols in scss, created to save lines of css code (and I think you do). But to know exactly the final compilation to css from scss code, you need to publish the whole scss code, including the files import from the scss file itself.
I hope I made it more clearly now.

Resources