Apply styles to MTableEditRow action component - material-table

I'm trying to apply styling to MTableEditRow actions component which comes from MUI. I've tried doing it with actionCellStyle and overriding action components but they do not apply to that specific element. The only solution which worked for me so far is using styled components (or styled MUI API) like so :
const StyledEditRow = styled(MTableEditRow)({
verticalAlign: "top",
height: "110px",
"& .MuiTableCell-root": { padding: "20px 5px !important" }
})
I would like to avoid using !important to override the style applied in the component if at all possible. It's a little bit weird that actionsCellStyle works only for one set of actions, or is there something I'm missing? Any help would be great!

Related

React Native - What's the best way to provide a global theme?

I've started using RN recently and have been doing some research on the implementation of themes and/or a dark-light mode. Here's roughly how I understand the two main options so far:
Context: Easy setup and can be accessed via hook inside the component that needs it. I count things like the React Navigation themes since that works, in essence, the same way(?)
Styled Components: Essentially just replacing the components with custom ones that access the current theme and that can then be set up to change their props on toggle if needed.
What I don't like about context, is that (the way I understand it) it wouldn't let me access the theme when using a StyleSheet, since that's outside the component. With the styled components on the other hands I'm not sure if I can cover all options inside my custom components, wouldn't I still need some sort of hook in each component anyway?
I was also thinking about just saving the current theme into my Store (in my case Zustand), together with an action that lets me toggle to a dark-mode. But so far, I haven't really seen anyone else do that, is there a downside to doing it that way?
It's not hard to pass context to your stylesheet, it just requires a bit of extra boilerplate. Something like the below:
import ThemeContext from '<path>';
export default () => {
const theme = useContext(ThemeContext);
const stylesWithTheme = styles(theme);
return <Text style={stylesWithTheme.text>Hi</Text>;
}
const styles = theme => StyleSheet.create({
text: {
color: themeStyles.color[theme];
}
});
const themeStyles = {
color: {
dark: '#FFF',
light: '#000',
},
};
I don't think using styled components would be a big departure from the above scheme.
If you did store your theme in state, and define your styles within the body of the component, that could be a savings in boilerplate. It's up to you whether having your styles in the component body is acceptable.
Side note, if you're already using a state manager, I would recommend not mixing it with the Context API without knowing more. It's simpler to have one solution there.

How do I use SCSS variables with data-attributes in Vue JS and Bootstrap Vue

I'm trying to have a Dark Theme button on my application and change the whole theme in a click. It is already working but I wanted to find an easier way to accomplish that.
I have created a button in the navbar that sets a localStorage variable to "dark" or "light" on click. Upon loading the application, its store will read the localStorage and have it available to the whole application.
Excerpt from store.js:
state {
...
theme: localStorage.getItem('theme') || 'light',
...
}
In my application, if I want to change the theme to a breadcrumb, I would do:
<b-breadcrumb :data-theme="theme">
<b-breadcrumb-item active>Start</b-breadcrumb-item>
</b-breadcrumb>
import {mapState} from 'vuex'
export default {
...
computed: {
...mapState(['theme'])
}
}
and in the custom.scss file:
[data-theme="dark"] {
$breadcrumb-bg: $dark !important;
}
And it would have changed the whole component color.
This does NOT work.
However, this DOES:
.breadcrumb[data-theme="dark"] {
background-color: $dark !important;
}
My question is: Is there an easy way to change all components using data attributes and SCSS variables or do I have to mannually select classes and change the components I want?
Unfortunately it is not possible to use Sass variables in custom data attributes as I wanted because the specification for data attributes won't allow them. They expect a DOMString name, not a Sass variable.
https://html.spec.whatwg.org/multipage/dom.html#custom-data-attribute

React Native Styling Precedence

This question is about using an array arg for the styling prop on a react component:
style={[styles.localTextStyle, textStyle...]}
As I understand precedence is from last element to first. So in the example above textStyle would overwrite styles.localTextStyle. This is good, however, I am making a custom component and I want to be able to specify inline props from the parent and have the inline be of highest precedence yet not overwrite previous styles if no prop is provided.
For example, if I were writing a custom component called Text:
<Text style={[styles.localTextStyle, textStyle, {
color: color
}]}>
I would use localTextStyle as defaults then styling passed from parent called textStyle, and finally the prop called color to set the color. This only works when the prop color is defined, otherwise, it will overwrite color to unset despite it possibly being set in textStyle for earlier styling.
So I'm wondering what the best way to circumvent this is. I currently have wrapped the final arg in a function called Clean which returns a new object with only defined keys-values. That works but it makes the code messy and I'd be shocked if someone didn't have a smarter, better way to do this.
<Text style={[styles.localTextStyle, textStyle, Clean({
color: color
})]}>
It's written inside the Documentation that :
You can also pass an array of styles - the last style in the array has precedence, so you can use this to inherit styles.
And I checked and It's like that :
[Component-Style] < [inside-array] < [outside-the-array]
like this :
TSButton has it's own styling in it's declaration
<TSButton style={[Style.button,{padding:0,width:50,height:20}]} />
So here the priority is as >>
TSButton Styling < Style.button < padding , width, ...

Preventing parent site styling affecting Vue JS component styling

I'm building a Vue JS plguin with some scoped styling, it works perfectly fine within another website when including it as a component, e.g: <my-component></my-component>.
However, the styling that I've added to the component is scoped to the component which means it doesn't affect the parent's site styling, however the parent's site styling DOES affect my component's styling, is there a way to prevent this without being super specific with my component's styling and using !important for everything?
Scoped styles work by adding a special key to your selectors. So your component would not affect other components. Parent components still may affect your component styling. And global styles also can intervene.
Well, you have 2 options if you don't want to use !important
First, and preferred - use specific BEM naming.
It is really easy to implement by using sass (scss).
e.g.
.mycompoment{
background:#fff;
&--body{
color:#eb0b0;
&--title{
font-size:5rem;
}
}
&--footer{
position:relative;
}
//etc
}
which would compile to the following css:
.mycompoment {
background: #fff;
}
.mycompoment--body {
color: #eb0b0;
}
.mycompoment--body--title {
font-size: 5rem;
}
.mycompoment--footer {
position: relative;
}
The other option is to increase your selector's specificity.
Try to use more direct descendant selectors. >
But still, outer css may still affect the values you don't even think of specifying.
For example position:absolute; top:-20px; or box-sizing/display/opacity and many different props your aren't aware of.

Get CSS property values from a component's "style" prop

I'm writing a React Native component for a library and I want users to be able to style it using the style property, just like React.View and other built-in components.
However, since my component is actually made up of a few nested views, I need to do some calculations to figure out what styling to put on the inner ones. For example, I might need to adjust the sizing of an image based upon the thickness of a border around it, or adjust a highlight color based upon the given text color, or in some other way infer some piece of styling from another piece of styling.
To do this, I need to be able to extract the actual CSS properties (like borderWidth: 2 or backgroundColor: 'pink') out of whatever gets passed as the style prop. This is fine as long as it comes as a plain object, but it may also be the result of a call to React.StyleSheet.create. This seems to be an opaque object with all selectors simply mapped to numeric IDs.
How can I resolve these and get the actual CSS properties, in order to do anything more complicated with them than simply passing them straight on to a View?
The built-in StyleSheet.flatten function (or the identical flattenStyle function) can turn anything that can legitimately be passed to the style prop into an object mapping CSS property names to values. It works on plain objects, IDs returned by StyleSheet.create(), and arrays.
Example usage to check the width specified in the style prop from within a Component definition:
import { StyleSheet } from 'react-native'
// ... then, later, e.g. in a component's .render() method:
let width = StyleSheet.flatten(this.props.style).width;
You need to import StylesheetRegistry:
StyleSheetRegistry = require("../../node_modules/react-native/Libraries/StyleSheet/StyleSheetRegistry"),
Then pass in the style ID:
var style = StyleSheetRegistry.getStyleByID(this.props.style)
Please have a look on https://github.com/vitalets/react-native-extended-stylesheet#underscored-styles
Style created via extended stylesheet contains original values in underscored prop:
const styles = EStyleSheet.create({
text: {
fontSize: '1rem',
color: 'gray'
}
});
In runtime:
styles = {
text: 0,
_text: {
fontSize: 16,
color: 'gray'
}
}