Conditional formatting in AppMaker table - google-app-maker

Have a data table in AppMaker and would like to do conditional formatting (Green to Red) in several columns based on the field value.
For example if ROI is over 40% give the number a dark green bg, 20% light green, < 0% red, etc.
Ideally I want to do a gradient like excel but that might be too complicated. Any help would be appreciated.

Couple of assumptions, I am guessing your column is a vertical/horizontal/fixed panel or some other type of widget that you can edit in App Maker's property editor and that ROI is a field in your datasource. You can get this accomplished by setting 3 style classes in your 'Style Editor' like this:
.dark-green {
background: linear-gradient(to bottom, darkgreen, green);
}
.light-green {
background: linear-gradient(to bottom, green, lightgreen);
}
.red {
background: linear-gradient(to bottom, darkred, red);
}
Then in the property editor for your widget go to 'Display' - 'styles' and bind your styles as follows:
#datasource.item.Percent === 0 ? 'red' : #datasource.item.Percent > 0 && #datasource.item.Percent <= 0.2 ? 'light-green' : #datasource.item.Percent > 0.2 ? 'dark-green' : ''
You can play around with the CSS for the background and such once you have your classes and binding for the styles accomplished to find a visual look that you like.
To apply this concept to the entire table row and still include the 'app-ListTableRow' and 'hoverAncestor' styling you would bind your table row styles as follows:
#datasource.item.Percent === 0 ? ['red','app-ListTableRow','hoverAncestor'] : #datasource.item.Percent > 0 && #datasource.item.Percent <= 0.2 ? ['light-green','app-ListTableRow','hoverAncestor'] : #datasource.item.Percent > 0.2 ? ['dark-green','app-ListTableRow','hoverAncestor'] : ['app-ListTableRow','hoverAncestor']

Related

Using styled-component, how can a single component have different stylings based on different situations?

Sandbox: https://codesandbox.io/s/nice-kirch-i1y58?file=/src/App.js:1384-1449
I have three calculations that each spit out a value to an output component. I use the same output component three times. The first Output component changes background colors based on the output value that's being calculated.
Now I want totally different background colors for the second calculation based on different values.
And I want the third output box to not change colors - just a solid background color regardless of the value in it.
How would I go about doing this? Switching background color styling based on context. Here's the code sandbox for this: Click Here. The only thing I can think of is to create three different output components instead of trying to use the same one but I feel like there might be a better way to achieve this.
Here is the little snippet of code for the Output box styled components that's changing the colors of the first box - Output.styles.js:
import styled from "styled-components";
export const OutputBox = styled.div`
box-sizing: border-box;
border-radius: 5px;
width: 195px;
height: 56px;
padding: 18px 10px;
font-size: 16px;
color: #000000;
background-color: ${(props) =>
props.color >= 101
? "red"
: props.color >= 30 && props.color <= 60
? "yellow"
: props.color >= 61 && props.color <= 100
? "blue"
: "pink"};
`;
And in Output.js:
const Output = ({ title, value, color }) => (
<div>
<OutputLabel>{title}</OutputLabel>
<OutputBox color={color}>{value}</OutputBox>
</div>
);
And in App.js:
<Output color={outputOne} title="Output One" value={outputOne} />
This is how I want my second output box background color to change:
background-color: ${(props) =>
props.secondColor >= 90
? "gray"
: props.secondColor >= 89 && props.secondColor <= 50
? "teal"
: props.secondColor >= 49 && props.secondColor <= 25
? "purple"
: "green"};
And my third output box I just want it to be one color:
background-color: "maroon"
You have two options that I think would work well for you. Both are based on conditional statements. I think all you need to use is move your conditional statements into the component instead of inside of the styles. You can use the conditional statement to add a class to the input box that has a style with the background color you like or overwrite any styles with inline styles and the backgroundColor attribute. I think in this case using inline styles might be easier to just add into your output component:
const color = props.secondColor >= 90 ? "gray" : ...rest of your code
<input style={{backgroundColor: color}} />

Use value from list as selector SCSS

I'm passing a list into a mixin to reduce the number of parameters I have to pass into my mixin. The mixin code can be seen below.
#mixin colorMedal($medalData) {
background-image: linear-gradient(
45deg,
nth($medalData,2) 0%,
nth($medalData,2) 50%,
nth($medalData,1) 50.1%,
nth($medalData,1) 100%
);
#{nth($medalData,0)} ~ .medal__ribbon--left {
background: nth($medalData,3);
}
#{nth($medalData,0)} ~ .medal__ribbon--right {
background: nth($medalData,4);
}
}
The list that im passing looks something like this
$platinum: ".medal__platinum", $medal-platinum, $medal-platinum-dark,
$medal-platinum-ribbon, $medal-platinum-ribbon-dark;
And the call of the mixin is :
#include colorMedal($platinum);
The code that seems to be causing a compile error is
#{nth($medalData,0)}
There must be a way to do this since you can pass in multiple values on their own. Is there a way to use a value from a list as a selector?
sass list starts at index 1 not 0
so change this from
#{nth($medalData,0)}
to
#{nth($medalData,1)}
you can debug the changes in codepen
https://codepen.io/srajagop/pen/wvBrzjO?editors=0102

Use SASS to dynamically add color stops to linear-gradient

Using SASS, I am trying to create a dynamic linear-gradient, so if I have an array of colors, I would like to loop through it and add each color to the gradient.
#import "compass";
$colors: red green blue;
$numColors: length($colors);
div {
$g: nth($colors, 1);
#for $h from 2 to ($numColors + 1) {
$g: $g , nth($colors, $h);
}
border: $g;
background: linear-gradient($g);
}
This results in the following error
At least two color stops are required for a linear-gradient
Removing the background parameter will compile, and looks like this
border: red, green, blue;
(I know that's not a valid border, I just wanted to "trace" out $g)
How can I dynamically iterate through an array and create a linear gradient?
You have 2 problems here.
linear-gradient is a custom Compass function, that's what's generating that error. As such, it expects a specific number of arguments.
You're not creating a list with 3 elements in it, you're creating a list with a single element in it that looks something like this: [[red, green], blue]. The first element of the list is a list containing 2 elements.
What you're needing here is the append() function:
div {
$g: nth($colors, 1);
#for $h from 2 to ($numColors + 1) {
$g: append($g , nth($colors, $h));
}
border: $g;
background: linear-gradient($g);
}
That will give you your expected output:
div {
border: red green blue;
background: linear-gradient(#ff0000, #008000, #0000ff);
}

How do I specify a single global background image using multiple background images?

I have several containers with multiple background images specified for each of them and separated by comma, where one of the background images is the same for every container.
.foo_1 {
background-image: url(../img/01.png), url(../img/photo1.jpg);
}
.foo_2 {
background-image: url(../img/01.png), url(../img/photo2.jpg);
}
.foo_3 {
background-image: url(../img/01.png), url(../img/photo3.jpg);
}
.foo_1, .foo_2, .foo_3 {
background-position: top left, center center;
background-repeat: repeat, no-repeat;
background-size: auto, cover;
}
Is there any way to avoid repeating the image which is used in each class, while still keeping the structure of a background image and allowing for the same manipulation as of a normal background-image property ?
Unfortunately, due to how the cascade works, it is not possible to specify multiple background layers in different rulesets without redeclaring the same background layer in each ruleset. See my answer to this related question for details:
A comma-separated list of background layers counts as a single value for the purposes of the cascade, which is why your second background declaration completely overrides the first.
While background is a shorthand for several other properties, it is not a shorthand for individual background layers, as they do not have their own properties. Since individual layer properties don't exist, you cannot use the cascade to override only certain layers while keeping the rest.
you can user repeat-x or repeat property.
but first of all you have need using Photoshop make there different images for each container :
1. first_img.jpg ( img1.jpg + imga.jpg)
1. second_img.jpg ( img1.jpg + imgb.jpg)
3. third_img.jpg ( img1.jpg + imgc.jpg)
.foo_1 {
background: url(../first_img.jpg) repeat-x or repeat ;
}
.foo_2 {
background: url(../second_img.jpg) repeat-x or repeat ;
}
.foo3 {
background: url(../third_img.jpg) repeat-x or repeat ;
}
Thanks.

How can I build a string in a loop for a dynamic gradient?

I want to be able to send in a few different colors and percentages, as a dynamic length list, to a LESS loop, to create a gradient. At the same time, I'd also like to prepend browser prefixes. The reason for this request is because I'm using CSS gradients in place of graphics for speed and minimizing requests.
Here's how I'm doing it now, but I'd like a more flexible solution:
.mkgrad(#gclrs, #gdir) {
#m:length(#list);
.looppref(#m, #j: 1) when (#j =< #m) {
#mypref: extract(#list, #j);
background:~"#{mypref}-linear-gradient(#{gdir}, #{gclrs})";
.looppref(#m, (#j + 1));
}
.looppref(#m);
.mkdir() when (#gdir = left) {
background:linear-gradient(to right, #gclrs);
}
.mkdir() when (#gdir = top) {
background:linear-gradient(to bottom, #gclrs);
}
.mkdir;
}
I'm calling this with the following:
#str1:fade(#cgray, 50%);
#str2:fade(#cwhite, 50%);
#str3:fade(#cblack, 50%);
#glist:#str1 0%, #str2 30%, #str3 100%;
background:#str3;
.mkgrad(#glist, left);
It's working, but I'd like to be able to merge the #str variables into the above loop so I can just send in a list of colors and percentages, and have it loop the list to build out a string for the background.
Can this be done? Is it possible using a mixin perhaps?
If I understand the goal correctly what you need is "Property Values Merge" feature so together with certain "Pattern-matching" optimizations the mixin could look like (assuming Less 1.7.x or higher, but I tested this only with v2):
// usage:
#gray: #010101;
#white: #020202;
#black: #030303;
#gradients: #gray 0%, #white 30%, #black 100%;
div {
.make-gradient(#gradients, left);
// or just:
// .make-gradient(#gray 0%, #white 30%, #black 100%; left);
}
// impl.:
.make-gradient(#gradients, #direction, #fade: 50%) {
background+: ~"linear-gradient(" #dir;
.loop(length(#gradients));
.loop(#i) when (#i > 0) {
.loop((#i - 1));
#gradient: extract(#gradients, #i);
#color: extract(#gradient, 1);
#stop: extract(#gradient, 2);
background+: fade(#color, #fade) #stop;
}
background+_:);
.dir(#direction);
.dir(#dir_) {#dir: #dir_}
.dir(left) {#dir: to right}
.dir(top) {#dir: to bottom}
}
I did not include any vendor prefixing because of tools like Autoprefixer (especially since it's now included as a plugin for Less v2), but I guess you'll easily add that yourself if you still find such kludge worthy.
P.S. As suggested in comments below: background+_:); works only in v2 (so it's more like an unintended bogus), more safe syntax is obviously background+_: ~")";
You could just use this mixin I created a few weeks back,
Rotatable Multi-stop SVG linear gradient mixin
It is as simple as
.multigradient(rgb; 168; #rgb; 2, 1); // id; degrees; colorstring; ratio
once you've built your colorstring, e.g.
#rgb: red 0, green 50%, blue 100%;
If you look at the code in this mixin, there is a function which builds an svg 'colorstop' string by looping through multiple values.

Resources