How to change ag-grid row group indent? - css

I want to change (increase/decrease) the magnitude of indent (current default is 28px) for each inner group in my Tree Data. However, I could not find any configuration options for the same in the documentation. The closest thing I could find was suppressPadding, which disables padding altogether. I tried using DOM piercing CSS but found that every level has a different CSS class (ex. ag-row-group-indent-2), which makes writing a general CSS rule in my container component difficult.

Currently, I'm overriding the style in a loop, which seems to be working
// Taken from https://github.com/ag-grid/ag-grid/blob/master/dist/styles/ag-theme-base/sass/parts/_grid-layout.scss
// support 20 levels here because row group indentation is used for tree data which can be quite deep
#for $i from 1 to 20 {
.ag-row-group-indent-#{$i} {
padding-left: $i * 8px;
}
.ag-row-level-#{$i} .ag-row-group-leaf-indent {
margin-left: 40px;
}
}

You can add a cellStyle callback that computes the padding-left value for each cell based on its current group level.
defaultColDef: {
cellStyle: (params) => {
const { level } = params.node;
const groupCell = params.value === params.node.key;
const indent = 28; // change this value to your liking
if (groupCell) {
return {
paddingLeft: (level + 1) * indent + "px"
};
}
}
},
If you use this approach, remember to suppress the initial css padding value from agGrid or both agGrid and your padding values will add up.
::ng-deep .ag-cell-wrapper.ag-row-group[class*="ag-row-group-indent"],
::ng-deep .ag-cell-wrapper.ag-row-group-leaf-indent[class*="ag-row-group-indent"] {
padding-left: 0;
}
Live Demo

If you're using SCSS and theming, you can change the indent by setting the value of row-group-indent-size, like this:
:root {
#include ag-theme-balham((
row-height: 20px,
cell-horizontal-padding: 8px,
row-group-indent-size: 18px
));
}
Reference: https://www.ag-grid.com/javascript-data-grid/global-style-customisation-variables/

Related

How to add custom padding-right to tailwind?

I want a larger value for padding right than tailwind currently offers (pr-96 which is around 24rem) Iā€™d like something around 40rem for my project.
Following documentation, I tried, but I cannot run npm run build without an error.
// tailwind.config.js
module.exports = {
theme: {
padding: {
xxl: 'padding-right: 40rem',
}
}
}
ā€™ā€™ā€™
Error:the xx class does not exist, but xx does.
If I remove the code I added above, error goes away.
You don't need to specify the property padding-right in your creation of the xxl utility only the value and unit, this line:
xxl: 'padding-right: 40rem'
should be:
xxl: '40rem'
This will give you an xxl size of 40rem for all padding classes p-xxl, pr-xxl, pl-xxl, etc...
However, you should only use padding as a direct child of theme when you want to replace all padding utilities. If you wanted to just add this size to the existing padding sizes you should use extend inside theme like this:
// tailwind.config.js
module.exports = {
theme: {
extend: {
padding: {
xxl: '40rem'
}
}
}
}

SASS Customize Class Names with Variables

Is there any way to customize the variables in SASS?
For example:
.m-b-{$number} {
margin-bottom: $number;
}
If I give class="m-b-50" to an element, it should take margin-bottom 50. I just want to know if it is possible with SASS.
Yes it is possible with the help of variable interpolation or variable substitution which uses #{} for variable substitution in SASS and mixins which is a block of code just like function.
Interpolation is the process of evaluating an expression or a string containing one or more variables, yielding a result in which the variables are replaced with their corresponding values.
Simple example of interpolation and set values to the css property in SASS:
$number:60;
$n: 20px;
.m-b-#{$number}{
margin-bottom: #{$number}px;
margin-top: $n;
}
To create customize class names, will use mixins:
#mixin margin-class($side, $number) {
$firstLetter: str-slice($side, 0, 1);
.m-#{$firstLetter}-#{$number}{
margin-#{$side}: #{$number}px;
}
}
$margins: (10, 20);
$sides: ("top", "right", "bottom", "left");
#mixin generate-margin(){
#each $margin in $margins{
#each $side in $sides{
#include margin-class($side, $margin);
}
}
}
#include generate-margin();
Here, generate-margin() will get executed which will call margin-class() for each $margins and $sides, and will generate the below CSS classes:
.m-t-10 {
margin-top: 10px;
}
.m-r-10 {
margin-right: 10px;
}
.m-b-10 {
margin-bottom: 10px;
}
.m-l-10 {
margin-left: 10px;
}
.m-t-20 {
margin-top: 20px;
}
.m-r-20 {
margin-right: 20px;
}
.m-b-20 {
margin-bottom: 20px;
}
.m-l-20 {
margin-left: 20px;
}
That's the one way when you want only for specific values, but if you want to create margin class for 0-20, you can loop thru 0 to 20 as shown below:
#mixin generate-margin(){
#for $margin from 1 through 20{
#each $side in $sides{
#include margin-class($side, $margin);
}
}
}
For anyone else facing this issue, here is how one can achieve this:-
#for $i from 1 through 10 {
.mb-#{$i} {
margin-bottom: #{$i}rem;
}
}
The answer is: no it is not possible. SASS is just a language to pre-generate CSS for you. There is no on-demand, dynamic creation of classes triggered by the contents of your HTML markup. When it comes time for the browser to render your HTML and apply your specified classes, it is still just using CSS. I.e. if you assign class="m-b-50" to an element, the class .m-b-50 must already be explicitly defined somewhere. As noted in the other answers, SASS can make it easier to generate a bunch of pre-defined classes but you must know which values you want to support up front.
Now, you could generate classes for some very large, all-inclusive range like -1000 to 1000 to effectively support all values you might ever try to use and it would seem to do what you wanted, but you would be forcing your users to download a larger CSS file with, most likely, a large percentage of it being unused CSS which is wasteful and can be inconsiderate in a world of paid & limited data plans.

What is the simplest way to divide a variable in SASS?

I would like to divide a SASS variable (which is a map value) by two, as follows:
$grid-gutter-widths: (
xs: 30px,
sm: 30px
...
);
$col-padding-xs: #{map-get($grid-gutter-widths, xs)/2}; // returns 15px
div {
padding-right: $col-padding-xs / 2; // returns 15px/2
}
Unfortunately I was expecting padding-right value to be 7.5px however it doesn't perform the division and instead returns a string with the slash in the middle. However this seems to work:
$col-padding-xs: 15px;
div {
padding-right: $col-padding-xs / 2; // returns 7.5px
}
So the map value must be the wrong type. Is there an easy way to cast it as a number so I can perform simple math on it in SASS?
Thanks for your help!
You are very close. It's a matter of the interpolation on the map-get that you have to remove. You can see the codepen for the compiled css.
$grid-gutter-widths: (
xs: 30px,
sm: 30px
);
$col-padding-xs: map-get($grid-gutter-widths, xs) / 2; // returns 15px
div {
padding-right: $col-padding-xs / 2; // returns 7.5px
}
In the new SASS version math.div takes the place instead of the divider symbol(/).
e.g. $col-padding-xs: #{map-get(math.div($grid-gutter-widths, xs), 2)};
It uses two numbers and divide them.
Source: https://sass-lang.com/documentation/breaking-changes/slash-div

CSS - How to select multiple attribute values?

If I have multiple div tags with an attribute containing different numbered values, and I would like to select only number 1 through 10, what is the most efficient way to do this in css?
Is there anything like e.g. .div[line-number=1-10] ?
This is not possible in the standard CSS. It is convenient to use a CSS preprocessor like SASS or LESS which allow you creating loops among many other features. An example with SASS:
$selector: '.div';
#for $i from 1 to 10 {
$selector: $selector + '[line-number=' + $i + ']';
}
#{$selector} {
// style
}
In pure CSS you are doomed to use this solution instead:
.div[line-number=1], .div[line-number=2], .div[line-number=3], .div[line-number=4], .div[line-number=5], .div[line-number=6], .div[line-number=7], .div[line-number=8], .div[line-number=9], .div[line-number=10] {
}
if you have the ability to modify the line-number attribute starting with 0 (01,02,03,04...10) you can do this:
div[line-number^="0"], div[line-number="10"] {
// css properties
}
if not see the answer from #jackBauer
You cannot specify line-number in range (1-10).
This is not available in attribute selector - https://www.w3.org/TR/css3-selectors/#attribute-selectors.
But alternatively you can apply css on each attribute value with something like below
div[line-number="1"] {
color: red;
}
div[line-number="10"] {
color: green;
}
<p>Use attribute selectors</p>
<div line-number="1">one</div>
<div line-number="2">two</div>
<div line-number="10">ten</div>
Hope this will help in some way(y).

Middle Child Pseudo-Class

Is there a way to use CSS selectors to get the middle child in a list of elements?
I know that there is no literal :middle-child selector, but is there another way without resorting to Javascript?
This has been working well for me:
*:not(:first-child):not(:last-child) {
...
}
You can see an example of this here: http://codepen.io/bentomas/pen/Gwqoe
The one caveat to this is that it only works in IE 9+: http://caniuse.com/#feat=css-sel3
While not elegant, if you know the upper and lower limits of the total number of elements, you could take a brute force approach to select the middle element.
For example, the following rules will select the middle element in a set of 5, 7, or 9 elements.
div:nth-child(3):nth-last-child(3) {
/* The middle element in a set of 5 is the 3rd element */
}
div:nth-child(4):nth-last-child(4) {
/* The middle element in a set of 7 is the 4th element */
}
div:nth-child(5):nth-last-child(5) {
/* The middle element in a set of 9 is the 5th element */
}
Or with Sass:
#for $i from 3 through 5 {
div:nth-child(#{$i}):nth-last-child(#{$i}) {
/* The middle element */
}
}
You can use the "not first and not last" approach, like so:
CSS
li:not(:first-child):not(:last-child) {
color:red;
}
HTML
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Check the JsFiddle
If you want to apply a style to all elements that are neither first children nor last children, you could use :not(:first-child), apply the style, and then use :last-child to 'take the style away' from the last element. But you'd have to think about what happens when there are less than 3 elements.
I've encountered the need to target the middle child on several occasions, and I've taken to using this sass mixin I wrote after referencing many similar questions, and their respective answers.
// Generate a reasonable number rules limited by $n.
#mixin middle-child($n) {
// There is no middle for nChildren less than 3,
// so lets just start at 3.
#for $i from 3 to $n {
// Find the middle, bias right for odd numbers.
$mid: math.ceil(math.div($i, 2));
// Select only those sets of children that number $i.
&:first-child:nth-last-child(#{$i}) {
// Select the middle child of that set.
~ :nth-child(#{$mid}) {
#content; // Apply your styles.
}
}
}
}
Usage:
.navigation {
background-color: #ba0020;
.nav-item {
color: white;
#include middle-child( 8 ) {
font-weight: 900;
}
}
}
Have you tried :nth-child(#) ?
Depending on which one you want to select you just replace # with the number.
Javascript is the only way to do this client side.

Resources