what is difference between '.attrs()' and 'props' in styled-components? - styled-components

const Input = styled.input.attrs(props => ({
// we can define static props
type: "text",
// or we can define dynamic ones
size: props.size || "1em",
}))`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* here we use the dynamically computed prop */
margin: ${props => props.size};
padding: ${props => props.size};
`;
render(
<div>
<Input placeholder="A small text input" />
<br />
<Input placeholder="A bigger text input" size="2em" />
</div>
);
This example was taken from an official documentation
but, I think this code is same as follows:
const Input = styled.input`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
margin: ${props => props.size};
padding: ${props => props.size};
`;
render(
<div>
<Input placeholder="A small text input" />
<br />
<Input placeholder="A bigger text input" size="2em" />
</div>
);
i don't understand to difference between '.attrs()' and 'props' in styled-components

Use inline styles (via attrs) if there are changes or something,like animation etc.
If styles dont change very often then use styled component with static and dynamic styles
Came across this already answered similar question. Kindly check it out

Related

Antd: How to custom close icon and search icon style?

I have a problem when custom close icon and search icon style.
I want to make search icon in left of input and close icon in right of input.
But now two icons is in right of input.
How can I fix this problem?
My code is here
.ant-input {
padding: 4px 10px 4px 40px;
border-radius: 20px;
&-search {
height: 40px;
width: 240px !important;
}
&-suffix {
width: 18px;
> i {
font-size: 18px;
}
}
}
}
<div className='user-list__tollbar--search'>
<Search
onChange={this.onSearch}
style={{width: 200}}
defaultValue={keyWord}
allowClear
/>
</div>
You can use antd Input to solve your issue
<Input
prefix={<SearchOutlined />}
placeholder="Search"
allowClear
/>

Unable to change label on input:checked

I'm attempting to follow this example (https://codesandbox.io/s/oYQ21A4wz) in a larger form and am really struggling to figure out how to change the label of the input on a :checked state for a styled-component in React. I'm using the 4.2 of styled-components. Any help would be GREATLY appreciated as I've been staring at this for a couple days.
I'm able to get the parent selectors working in other cases (eg: hover) but for some reason I cannot seem to target the Label from its child.
const CheckBoxDoors = props => {
const Label = styled.label`
display: inline-block;
background: rgba(255, 255, 255, 0.9);
border: 2px solid rgba(139, 139, 139, 0.3);
color: #adadad;
border-radius: 25px;
padding: 1px 4px;
margin: 1px;
white-space: nowrap;
`;
const Input = styled.input`
&:checked + ${Label} {
background: blue;
}
`;
return (
<div className="form-group, checkbox">
<CheckboxContainer>
<CheckboxTitle>{props.title}</CheckboxTitle>
<CheckboxGroup>
{props.options.map(option => {
return (
<Label key={option} className="checkbox-inline">
<Input
id={props.value}
name={props.name}
onChange={props.handleChange}
value={props.name + ' ' + option}
checked={
props.selectedOptions.indexOf(props.name + ' ' + option) >
-1
}
type="checkbox"
/>
{option}
</Label>
);
})}
</CheckboxGroup>
</CheckboxContainer>
</div>
);
};
Check this one out:
const Input = styled.input`
&:checked + ${Label} {
background: blue;
}
`;
This rule &:checked + ${Label} means 'when I am checked, the sibling Label component right below me will have these styles'; i.e
<>
<Input id={id}... />
<Label htmlFor={id}... />
</>
However, your component structure looks like this:
<Label>
<Input ... />
</Label>
You'd have to change it to the structure mentioned above.
Also note that you shouldn't declare your styled components inside another component, it'll hurt performance badly. Instead, you should do:
const Input = styled.input` ... `
const Label = styled.label` ... `
const CheckBoxDoors = props => ...

how to draw excel style data bars in angular?

I want to add databars behind values in the selected column in my grid like the Data Bars Conditional Formatting option in Excel.
This answer show me the thing using jquery data table, Can anyone give me the idea for this in angular 6.
Note: I am not using any 3rd party grid, I have created this grid from my own.
It should look something like this.
Not sure in what scenario you want to add this, but have a look at this:
https://css-tricks.com/css3-progress-bars/
This is classic HTML and CSS "trick" to create a bar which you can define length of.
The basics of it is that you have a "wrapper" element that defines the maximum length, and a "bar" element inside that you set width: [0-100]% and a background color of that.
This would be an example on how to create a 50% wide blue bar.
.wrapper {
width: 100%;
}
.bar {
background: blue;
height: 5px;
}
<div class="wrapper">
<div class="bar" style="width: 50%"></div>
</div>
Use that to create an angular component that you can send you width to, something like this:
import { Component, Input } from '#angular/core';
#Component({
selector: 'app-bar',
template: `
<div class="wrapper">
<div class="bar" [style.width]="width"></div>
</div>
`,
styles: [`
.wrapper {
width: 100%;
}
.bar {
background: blue;
height: 5px;
}
`]
})
export class BarComponent {
#Input() width: number;
}
This will do the job.
#Component({
selector: 'my-app',
template: `
<div class="holder">
<div class="bar" *ngFor="let item of data">
<div #bar class="{{item >= 0 ? 'positive' : 'negative'}}">
<div class="size" [style.width.px]="getWidth(item, bar)">
{{item}}
</div>
</div>
</div>
</div>
`
})
class AppComponent {
maxValue = 100;
data: Number[] = [
10,20,30,-45,90,-90,-80,50,100
]
getWidth(dataItem: number, bar: HTMLElement):number {
return (parseInt(bar.offsetWidth) / this.maxValue) * Math.abs(dataItem);
}
}
CSS:
.holder {
border: 1px solid black;
margin: 10px;
padding: 5px;
width: 200px;
}
.bar {
border: 1px solid grey;
padding: 3px;
margin: 10px 5px;
text-align: center;
}
.positive {
color: blue;
width: 90px;
margin-left: 90px;
}
.negative {
color: red;
width: 90px;
margin-right: 90px;
.size {
margin-left: auto
}
}
.size {
background: green;
}
You can use primeNg data table, and their cell formatting feature, we can format each cell based on certain condition like changing the color or painting it, this may help you.
PrimeNg Cell Style

container with position relative shrinkwraps when images are floated

I have a website I am creating for a school project. I am very new to html and css. I have created div containers for the different sections of my pages. On my index page, I have 5 containers including the header and footer.
The containers are working everywhere except in 1 location where I am floating images. For some reason, the box is shrink-wrapping under the 3 images. I thought by placing a position:relative in the .container css rule, it would behave like it is with paragraphs and other elements. I would like that container to surround the pictures just like it is with the other boxes on the index page.
Here is the html for that specific container that is not working:
<div class="container">
<article>
<h2>Meet the Staff:</h2>
<div class="gallery">
<figure class="staff"><img src="images/mary.jpg" alt="mary the librarian" />
<figcaption>Mary the Librarian</figcaption>
</figure>
</div>
<div class="gallery">
<figure class="staff"><img src="images/ruth.jpg" alt="mary the librarian" />
<figcaption>Ruth the Assistant</figcaption>
</figure>
</div>
<div class="gallery">
<figure class="staff"><img src="images/esther.jpg" alt="mary the librarian" />
<figcaption>Esther the Research Librarian</figcaption>
</figure>
</div>
</article>
</div>
And here is the css:
.container {
width: 1000px;
height: auto;
margin: auto;
margin-bottom: 25px;
padding: 0 20px;
position: relative;
background: #fff;
box-shadow: 0 0 10px #b5b2ab;
}
figure img {
border: 1px solid #666;
background-color: #fff;
padding: 4px;
box-shadow: 2px 2px 4px rgba(0,0,0,.5);
}
figcaption {
font: Arial, sans-serif;
text-align: center;
margin: 10px 0 0 0;
}
figure {
display: block;
float: left;
width: 240px;
margin: 0 25px 25px 25px;
}
Here is the so you can see what is happening: http://www.ta5zc.com/
Thanks for any help you can provide. I can't seem to figure out what is wrong.
Embarrassing, but I figured it out. The container is acting just like it is supposed to. There was no elements below the images, so there was nothing to stay in place. Therefore, when I floated the images, the box moved up the page like it was supposed to. Like I said, I'm new at this ;-)

YUI Tutorial not working

Why does this code from this YUI3 example not work for me?
HTML:
<!-- The original body content is above -->
<div id="form_container">
<form class="yui3-widget-bd" id="theme_form" action="#" method="get">
<fieldset>
<h3>Update Theme</h3>
<label for="font_size">Font size:</label>
<input type="text" size="3" id="font_size" value="16px">
<label for="heading_color">Heading color:</label>
<input type="text" size="12" id="heading_color" value="#005A9C">
<label for="link_hover">Link hover backgound:</label>
<input type="text" size="12" id="link_hover" value="#ffa">
</fieldset>
<input type="submit">
</form>
</div>
Javascript:
// Create a new YUI instance, requiring stylesheet, overlay, slider, and the
// dd-plugin to make the overlay draggable
YUI({
filter: 'raw'
}).use("stylesheet", "overlay", "slider", "dd-plugin", function(Y) {
var myStyleSheet = new Y.StyleSheet(),
overlayContent = Y.one('#form_container'),
overlay, slider, slider_container, fontSizeInput;
// Create the Overlay, using the form container as the contentBox.
// The form is assigned a class yui-widget-bd that will be automatically
// discovered by Overlay to populate the Overlay's body section.
// The overlay is positioned in the top right corner, but made draggable
// using Y.Plugin.Drag, provided by the dd-plugin module.
overlay = new Y.Overlay({
srcNode: overlayContent,
width: '225px',
align: {
points: [Y.WidgetPositionAlign.TR, Y.WidgetPositionAlign.TR]
},
plugins: [Y.Plugin.Drag]
}).render();
// Slider needs a parent element to have the sam skin class for UI skinning
overlayContent.addClass('yui3-skin-sam');
// Progressively enhance the font-size input with a Slider
fontSizeInput = Y.one('#font_size');
fontSizeInput.set('type', 'hidden');
fontSizeInput.get('parentNode').insertBefore(
Y.Node.create('6 <span></span> 36'), fontSizeInput);
slider_container = fontSizeInput.previous("span");
// Create a Slider to contain font size between 6px and 36px, using the
// page's current font size as the initial value.
// Set up an event subscriber during construction to update the replaced
// input field's value and apply the change to the StyleSheet
slider = new Y.Slider({
length: '100px',
min: 6,
max: 36,
value: parseInt(Y.one('body').getStyle('fontSize')) || 13,
after: {
valueChange: function(e) {
var size = e.newVal + 'px';
this.thumb.set('title', size);
fontSizeInput.set('value', size);
myStyleSheet.set('body', {
fontSize: size
});
}
}
}).render(slider_container);
// The color inputs are assigned keyup listeners that will update the
// StyleSheet if the current input value is a valid CSS color value
// The heading input affects all h1s, h2, and h3s
Y.on('keyup', function(e) {
var color = this.get('value');
console.log(color);
if (isValidColor(color)) {
console.log("Valid color", myStyleSheet);
myStyleSheet.set('h1, h2, h3', {
color: color
});
}
}, '#heading_color');
// The link hover affects the background color of links when they are
// hovered. There is no way other than via stylesheet modification to
// change pseudo-class styles.
Y.on('keyup', function(e) {
var color = this.get('value');
if (isValidColor(color)) {
myStyleSheet.set('a:hover', {
backgroundColor: color
});
}
}, '#link_hover');
// Progressive form enhancement complete, now prevent the form from
// submitting normally.
Y.on('submit', function(e) {
e.halt();
}, '#theme_form');
// A rudimentary validator to make sure we're not trying to set
// invalid color values in StyleSheet.
function isValidColor(v) {
return /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(v) || /^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/.test(v) || /^[a-z]{3,}$/i.test(v);
}
});
CSS:
/* For supporting browsers, the overlay is rendered semi-transparent with
* fancy rounded corners */
.yui3-overlay {
background: rgba(128,128,128,0.3);
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
padding: 7px;
cursor: move;
}
.yui3-overlay-content {
background: rgba(205,205,205,0.3);
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
padding: 1px;
}
.yui3-overlay form {
background: #f2fbff;
border: 2px solid #fff;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
margin: 0;
padding: 0;
font-size: 13px;
}
.yui3-overlay fieldset {
border: 1px solid #bcd;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
margin: 0;
padding: 20px;
}
.yui3-overlay h3 {
border-bottom: 2px solid #fff;
color: #479;
background: transparent;
margin: 0;
font-size: 175%;
}
.yui3-overlay label {
display: block;
margin: 1.3em 0 0.5ex;
font-weight: bold;
color: #003;
}
.yui3-overlay p {
margin: 2em 0 0;
}
/* override the move cursor for the Slider */
.yui3-overlay .yui3-slider:hover {
cursor: default;
}
I just copied and pasted the code, can anyone help?
Your tag is missing class="yui3-skin-sam yui-skin-sam"
It appears to be working. I copied/pasted your code into this jsfiddle. Change with the slider and header color change field, it seems to update the color and size.
This is not the best forum to do support debugging.
You're welcome to ask in the #yui channel on freenode rather than go through slow, back and forth debugging here.

Resources