How to set custom style for blueprintjs component? - blueprintjs

I am using blueprintjs with react and would like to customize blueprint component's size and color.
For example, I have a spinner, and would like to customize it size to 30px.
<Spinner className={'customSize'}/>
Which customSize is
.customSize{
width: 30px;
}
However, it's not going to overwrite original size.
Is there a possible way to customize the size or color of spinner?
Thanks

You can either write a more specific style than the one BlueprintJS supplies. They have quite strict opinions about how their toolkit is supposed to render.
They do support different sizes for the Spinner component though:
<Spinner size={SpinnerSize.LARGE} />
The options in the SpinnerSize constant are SMALL, STANDARD or LARGE. Those map to numbers, meaning the size prop expects a number. Why not try to give it our own number?
<Spinner size={137} />
You can learn more in the docs here.

For <Spinner> component
Size:
The size prop accepts a number including the following constants:
SpinnerSize.SMALL
SpinnerSize.STANDARD
SpinnerSize.LARGE
<Spinner size={SpinnerSize.LARGE} />
<Spinner size={128} />
Color:
As far as I know, there is no built-in component prop accepted to change the color. You can however customize the spinner's css classes:
// MyComponent.jsx
import styles from './MyComponent.module.scss'
<Spinner className={styles.mySpinner} />
/* MyComponent.module.css */
.mySpinner :global(.bp4-spinner-track) { /* Unspinning part of circle */
stroke: #000;
}
.mySpinner :global(.bp4-spinner-head) { /* Spinning head */
stroke: #fff;
}
Other components
Size:
Some have the large prop, few ones have also the small prop.
<InputGroup small />
<Switch large />
Color:
You can use CSS, but there are also some predefined color constants available in JS side: https://blueprintjs.com/docs/#core/colors
import { Colors } from "#blueprintjs/core"
<Button style={{ color: Colors.BLUE3, background: Colors.LIME2}}/>

Related

Vuetify: How to set v-data-table row height manually?

How to set <v-data-table> row height manually ?
Setting the table to dense is some small enough for my needs.
By default, $data-table-dense-row-height is set to 32px !default;
Check this codesandbox I made: https://codesandbox.io/s/stack-70697036-bo4yx?file=/src/components/TableExample.vue
If you don't want to mess with SASS variables, or modify the value globally you can use the item-class prop of the v-data-table like this:
<v-data-table
:headers="headers"
:items="desserts"
:items-per-page="5"
class="elevation-1"
:item-class="setRowStyle"
>
</v-data-table>
You need to define a function to be able to apply css to the hole item row.
methods: {
setRowStyle(item) {
/* Here you can also do some validation
in case you want to apply different css
classes depending on item attributes
values */
return 'style-1'
}
}
And then you simply defined the css you want to be apply to your data-table rows:
<style>
.style-1 td {
height: 100px !important;
}
</style>
If you want to use a scoped css style block, you'll need to defined your css using deep selector to properly apply the height to td tags.
<style scoped>
>>>.style-1 td {
height: 100px !important;
}
</style>
If you also want to modify the row headers height, you can use the class attribute in your headers array.

Vuetify input color property works only when focused

I'm trying to understand how Vuetify's input color property is working and I can't find it in documentation, which simply states:
color
Applies specified color to the control - it can be the name of material color (for example success or purple) or css color (#033 or rgba(255, 0, 0, 0.5)). You can find list of built in classes on the colors page.
What I'm observing is that the color has effect only when the control has focus [LIVE DEMO], and goes back to default color when the control loses focus.
<v-text-field color="orange" label="label" />
Focused:
Not focused:
Is this by design, and is it specified anywhere?
Most importantly, how to affect the color of the not-focused state (preferably without custom CSS)?
To set the default color to v-text-field use the following css
-- #ff9800 (equivalenyt to orange color)
Working codepen is here https://codepen.io/chansv/pen/ZEEOXKN
.theme--light.v-text-field>.v-input__control>.v-input__slot:before {
border-color: #ff9800;
}
.theme--light.v-label {
color: #ff9800;
}
.theme--light.v-input:not(.v-input--is-disabled) input, .theme--light.v-input:not(.v-input--is-disabled) textarea {
color: #ff9800;
}
Github issue in vuetify https://github.com/vuetifyjs/vuetify/issues/3430

Vuetify themes with custom css

Let's assume I have something like the following:
<v-app>
<div :class="getCustomCss">Blah</div>
<v-app>
getCustomCss() {
return $this.vuetify.theme.dark ? 'whenThemeIsDark' : 'whenThemeIsLight';
}
<style>
.whenThemeIsDark {
border:1px solid white;
}
.whenThemeIsLight {
border:1px solid black;
}
</style>
What would be the best way to change the color of the divs border when toggling between light/dark themes?
Do I sit and watch the $this.vuetify.theme.dark property and manually change the border from the myDarkClass to myWhiteClass similar to what's shown above? Or do I somehow use the customProperties feature in the theme/options to do this (and how?). Or is there a better way of doing this I'm unaware of?
This is a simple example which only requests the css to change in one spot, but a real application may have tons of custom css on different pages that would keep needing checks like this. I could easily see that getting messy if there are watchers/checks everywhere.
I have read the https://vuetifyjs.com/en/customization/theme page and I have a feeling the Custom Properties section may be the key, but I'm not quite getting how to translate my example to their example.
A css class of theme--light or theme--dark is applied to the v-app v-application which will identify which theme is active for you without additional watchers.
Using your simplified example:
<style>
.v-application.theme--light {
border:1px solid white;
}
.v-application.theme--dark{
border:1px solid black;
}
</style>

What is the most performant way for dynamic styling in React-Native?

In React-Native, you can use Stylesheet to create css-like stylesheets. The main reason of using styleshee.create in favor of plain js-objects is increased performance. However, you often might want to style components dynamically, often based on their props. I basically found three approaches of doing this:
Note for the following examples: Consider const styles ... to be declared outside of the Component, as it's a common pattern and you might want to share styles between different Components. Consider everything below the tree dots as part of the render function.
Using an array of styles:
const styles = StyleSheet.create({viewStyle: {backgroundColor:'red'}})
...
return <View style={[styles.viewStyle, {color: this.props.color}]} />
Using Stylesheet.flatten:
const styles = StyleSheet.create({viewStyle: {backgroundColor:'red'}})
...
const flattenedStyle = StyleSheet.flatten(styles.viewStyle, {{color: this.props.color}})
return <View style={flattenedStyle} />
Using a function to create the stylesheet:
const styles = (color) => StyleSheet.create({
viewStyle: {
backgroundColor:'red',
color: color
}
})
...
const style = styles(this.props.color).viewStyle
return <View style={style} />
I am wondering which approach is the best regarding to performance, or if there even is another, more performant way? I think Option 2 and 3 are no way to go at all, because dynamically creating new stylesheets on prop-changes undermines the whole purpose of stylesheets. I am happy for any thought or hints on this subject!
Here you can do dynamic styling in react native for each styling.
Like this
<Text style={styles.simpleText('red')}>Required field</Text>
// In styling
const styles = StyleSheet.create({
simpleText: (colorProp = 'black') => ({ // default black set
fontSize: 14,
color: colorProp,
})
})
and you can also pass any data type for conditional styling
One of the approach
// homeSreen
<View style={styles.filterButton(isSelected)}>
<Text> Strawberry </Text>
</View>
// styles.js
import { StyleSheet } from 'react-native';
import { Colors } from '../../theme';
export default StyleSheet.create({
container: {
backgroundColor: Colors.lighter,
},
filterButton: isSelected => ({
padding: 15,
backgroundColor: isSelected? Colors.background.primary: Colors.background.secondary
}),
});
You could memoize stylesheet creation using React hooks, but first you need to do some performance checking in order to determine if stylesheet creation is in fact a CPU and/or memory hog worth optimizing.
Here's an example:
const styles = (color) => StyleSheet.create({
viewStyle: {
backgroundColor:'red',
color: color
}
})
/*
even though makeStyle is defined in EVERY render,
React will only run it ONCE for any given props.color distinct value.
The resulting value `styles` survives re-renders
*/
const makeStyle = () => styles(props.color)
const styles = useMemo(makeStyle, [props.color]);
And here's the official documentation.
Did you consider CSS in JS libraries like Styled components?
You can pass props and get dynamic style regard that:
https://styled-components.com/docs/basics#passed-props
Possibly a bit overkill for simple dynamic styling but Reanimated is very performant and will run the style transition at 60fps https://github.com/software-mansion/react-native-reanimated
It archives this by declaring all the styles needed for an animation/transition ahead of time and runs them on the native thread so there is minimal communication across the JS->Native code bridge.
There is a better explanation on their about page here https://docs.swmansion.com/react-native-reanimated/docs/about

Reusing existing span with custom attributes in CKEditor while changing background color

When changing the background-color, CKEditor wraps the selected content in a span element where the inline style is set.
I have an application to create interactive videos: it is possible to stop the playback in desired moments and, in these pauses, the viewer can jump to key moments of the video, or answer to quizzes, returning to specific points of the video if the answer was wrong, and so on. To create this interactive layer above the player I use the CKEditor with some custom plugins to create the interactive elements.
One of the plugins is used to create span elements with a custom attribute data-player-control:
span[data-player-control] {
background-color: #3366FF;
color: #FFF;
border-radius: 10px;
padding: 10px;
}
<span data-player-control="play">My element</span>
The value of the data-player-control attribute is not fixed (it can be specified in the plugin), and it is used to control the exhibition of the video.
When the editor is used to change the element background color, it wraps the element text in a new span, what results in:
span[data-player-control] {
background-color: #3366FF;
color: #FFF;
border-radius: 10px;
padding: 10px;
}
<span data-player-control="play">
<span style="background-color:#FF0000">My element</span>
</span>
These two nested span elements, with two distinct background colors, are undesired.
What I need is the inline style to be applied to the existing span element, resulting in:
span[data-player-control] {
background-color: #3366FF;
color: #FFF;
border-radius: 10px;
padding: 10px;
}
<span data-player-control="play" style="background-color:#FF0000">
My element
</span>
How can this be achieved?
Using dataFilter or htmlFilter is not a feasible solution, as they are executed in input or output data, when entering or existing the inline instance of the CKEditor. Using a transformation also is not a solution, as it uses a simplified form to represent the elements, not the real DOM.
Is there any callback function to use while editing the content (so I can change the DOM according to my needs)?
A simple solution is to listen to the change event in the editor instance and then modify the DOM in event.editor.ui.contentsElement.$ as desired.
You can try to use custom styles definition which is used for adding background-color. The colorButton_backStyle can be set in the editor config.
To override span element with some custom attributes, you can use:
config.colorButton_backStyle = {
element: 'span',
styles: { 'background-color': '#(color)' },
overrides: { 'element': 'span', attributes: { 'data-player-control': 'play' } }
};
So basically overrides attribute is used when applying background-color and there is a span with such attribute - it is replaced (but then the attribute also gets removed ). You can add attributes:
config.colorButton_backStyle = {
element: 'span',
attributes: { 'data-player-control': 'play' },
styles: { 'background-color': '#(color)' },
overrides: { 'element': 'span', attributes: { 'data-player-control': 'play' } }
};
So that overriding span also has your attribute. The problem with this solution is that:
When applying background color to other elements, span will also have data-player-control attribute.
When removing background color, the whole span gets removed.
The above solution may not fit your needs. Maybe there is different approach to the problem you are trying to solve?
As I understand from the question you would like the HTML to have defined structure the whole time (not only as output data), is that correct? What problem is structure with nested spans causing in your application/implementation?

Resources