I want to use the url I got as props from the styled component - styled-components

import React from "react";
import styled from "styled-components";
const topCate = (props) => {
return (
<TopCateList imgObj>
<p>{props.main_category_id}</p>
</TopCateList>
);
}
const TopCateList = styled.li`
width: 130px;
height: 60px;
border-radius: .3em;
border: 1px solid gray;
padding: .5em 0em;
text-align: center;
font-size: 0.975rem;
background-image: url(${props => props.backImg});
line-height: 3em;
font-weight: 500;
margin-right: .5em;
`;
export default topCate;
I want to use the url I got as props from the styled component.
It is not displayed on the screen.
What should I do?

You can extend a component in styled-components like in the code below :
Any props you pass in this component will be available to you as props like the url,color and backImg. Just make sure to pass the className to the li for it to apply the styles.
import React from "react";
import styled from "styled-components";
const List = (props) => {
return (
<li className={props.className}>
<p>{props.url}</p>
</li>
);
}
const TopCateList = styled(List)`
width: 130px;
height: 60px;
border-radius: .3em;
border: 1px solid gray;
padding: .5em 0em;
text-align: center;
font-size: 0.975rem;
background-image: url(${props => props.backImg});
line-height: 3em;
font-weight: 500;
margin-right: .5em;
color: ${props => props.color};
`;
export default TopCateList;
Usage
<TopCateList url="http://stackoverflow.com" color="red" backImg="./src/someimage.jpg">
Hope this helps !

Related

Styled component css helper not working with mixin

I want to change the StyledButton depends on the props passed. When complex is true, it's supposed to go to complexMixin and then determine what whiteColor passes. But even I pass whiteColor with true, the color is black, not white.
Does anyone have idea what's going on with it? Thanks!
Demo
import styled, { css } from "styled-components";
const complexMixin = css`
color: ${({ whiteColor }) => (whiteColor ? "white" : "black")};
`;
const StyledButton = styled.div`
border: 1px solid red;
height: 100px;
text-align: center;
margin: 20px;
font-weight: 700;
font-size: 40px;
color: ${({ complex }) => (complex ? complexMixin : "green")};
`;
const App = () => {
const isComplex = true;
const isWhite = true;
return (
<>
<StyledButton whiteColor={isWhite} complex={isComplex}>
ccc
</StyledButton>
<StyledButton complex={!isComplex}>BBB</StyledButton>
</>
);
};
usually, I write this kind of complicated CSS logic like this.
const complexMixin = css`
${({ complex, whiteColor }) =>
complex &&
css`
color: #000;
${whiteColor &&
css`
color: #fff;
`}
`}
${({ complex }) =>
!complex &&
css`
color: green;
`}
`;
const StyledButton = styled.div`
border: 1px solid red;
height: 100px;
text-align: center;
margin: 20px;
font-weight: 700;
font-size: 40px;
${complexMixin}
`;
For your mixin you can do this:
const complexMixin = ({ whiteColor }) => whiteColor ? "white" : "black";
And
color: ${({ complex }) => (complex ? complexMixin : "green")};
In your code we see that you want to add a "color: " in another "color: "

Error when setting the attribute on a styled component

I get an "Object(...)(...).attrs is not a function" error when I try setting the attribute of a styled input component, like so
import styled from '#emotion/styled'
const DateInput = styled.input.attrs({
type: 'date'
})`
width: 360px;
border: 1px solid #ccc;
border-radius: 5px;
height: 100%;
padding: 0px 12px 0px 20px;
`
Any idea of what I'm doing wrong?
Use:
import styled from "styled-components";
instead of:
'#emotion/styled'

Stripe creditcard elements not loaded in Safari browser

We use stripe v.3 to add creditcard for a customer. It works on all browsers chrome and firefox. But safari returns the following error.
ReferenceError: Can't find variable: elements
Tested on physical iphone device it seems older version cant create the stripe elements leaving the input field, clumpy and not showing the CC information. Check screenshot.
The bug occurs on iOS version 11.3.1 and down. The iframe is showing in the source elements but dont add the class .StripeElement to the dom.
import {
Component,
Inject,
ViewChild,
ElementRef,
AfterViewInit,
OnDestroy,
ChangeDetectorRef,
} from '#angular/core';
import { NgForm } from '#angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '#angular/material/dialog';
import { ToastrService } from 'ngx-toastr';
import { PaymentService } from '#services/http/payment.service';
import { StateService } from '#services/Logic/state.service';
import { TranslatePipe } from '#app/pipes/translate.pipe';
#Component({
selector: 'app-add-credit-card-dialog',
templateUrl: 'addCreditCard.html',
styleUrls: ['addCreditCard.scss', '../../dialogs.scss'],
})
export class AddCreditCardDialogComponent implements AfterViewInit, OnDestroy {
#ViewChild('cardInfo', { static: true }) cardInfo: ElementRef;
card: any;
cardHandler = this.onChange.bind(this);
error: string;
cardholderName: string;
constructor(
private cd: ChangeDetectorRef,
private toastr: ToastrService,
private translatePipe: TranslatePipe,
private stateService: StateService,
private paymentService: PaymentService,
public dialogRef: MatDialogRef<AddCreditCardDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any
) {}
ngAfterViewInit() {
this.card = elements.create('card');
this.card.mount(this.cardInfo.nativeElement);
this.card.addEventListener('change', this.cardHandler);
// Force the Element frame to paint once it is visible on the page
setTimeout(() => {
this.forceReflow('.StripeElement');
}, 1000);
}
ngOnDestroy() {
this.card.removeEventListener('change', this.cardHandler);
this.card.destroy();
}
forceReflow(selector) {
const el = document.querySelector(selector);
if (el) {
const initialDisplay = el.style.display;
el.style.display = 'none';
el.offsetHeight;
el.style.display = initialDisplay;
}
}
onChange({ error }) {
if (error) {
this.error = error.message;
} else {
this.error = null;
}
this.cd.detectChanges();
}
async onSubmit(form: NgForm) {
if (!this.cardholderName || this.cardholderName.length === 0) {
return this.toastr.error(this.translatePipe.transform('TOAST_MESSAGES.ERROR.MISSING_CARDHOLDER'));
}
this.stateService.toggleWaitingPage(true);
// create a Setup Intent for this card
const { setupIntent, error } = await stripe.handleCardSetup(
this.data.client_secret,
this.card,
{
payment_method_data: {
billing_details: { name: this.cardholderName },
},
}
);
if (error) {
this.toastr.error(error.message);
this.stateService.toggleWaitingPage(false);
} else {
// create a Payment Method from the previously created Setup Intent and attach it to the Customer
const paymentMethod = await this.paymentService
.attachPaymentMethod({ payment_method: setupIntent.payment_method })
.toPromise();
this.close(paymentMethod);
}
}
close(data: any = null): void {
this.dialogRef.close(data);
}
}
form {
display: flex;
flex-direction: column;
align-items: center;
width: 95%;
margin: auto;
.form-row {
width: 100%;
margin: 0 0 20px;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2);
border-radius: 5px;
padding: 10px;
height: 40px;
#card-errors {
font-size: 12px;
color: #f82e42;
}
}
}
p {
color: #707070;
}
.input_area{
width: 100%;
text-align: center;
padding-bottom: 115px;
}
.body_area{
display: block;
height: 100%;
.attention{
display: flex;
margin: 20px 0px;
height: 100%;
padding: 5px 0px;
background-color: #F6F9FC;
.notranslate {
color: #89b153;
font-size: 18px;
margin-left: 8px;
padding-top: 2px;
padding-right: 5px;
}
p{
text-align: left !important;
margin-bottom: 0px !important;
}
.notranslate{
color: #707070;
place-self: center;
}
}
}
.header_wrapper{
display: block;
height: 100%;
.pinpay{
margin-bottom: unset !important;
font-weight: bold;
font-size: 17px;
color: #4a4a56;
}
.img {
height: 80px;
width: 80px;
margin-top: 10px;
margin: auto;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
border-radius: 500px;
#media (max-width: 320px) and (max-height: 438px) { display: none; }
.image-icon{
height: 60px;
width: 60px;
margin-top: 3px;
margin-left: 8.4px;
}
}
}
#cardholder-name {
width: 95%;
margin-bottom: 20px;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2);
background: transparent;
border: none;
}
<div class="dialog_container">
<div class="header_row">
<div class="header_left"></div>
<span class="close" (click)="close()">✕</span>
<h5 id="header_title">{{ 'DIALOGS.ADD_CREDIT_CARD.TITLE' | translate }}</h5>
</div>
<div class="header_wrapper">
<div class="img">
</div>
<div style="display: flex; margin-bottom: unset">
<p class="pinpay">PinployPay</p>
<span></span>™
</div>
<p class="pinpay1">Sikker handel</p>
</div>
<div class="body_area">
<div class="attention">
<mat-icon [matTooltip]="'PAGES.SETTINGS.PROFILE.COMPLETION_RATE_INFO' | translate">info</mat-icon>
<p>{{ 'DIALOGS.ADD_CREDIT_CARD.MESSAGE' | translate }}</p>
</div>
<p>
<mat-icon class="notranslate">remove_shopping_cart</mat-icon>{{
'DIALOGS.ADD_CREDIT_CARD.MESSAGE_1' | translate }}
</p>
</div>
<div class="input_area">
<input
id="cardholder-name"
[(ngModel)]="cardholderName"
[placeholder]="'DIALOGS.ADD_CREDIT_CARD.CARDHOLDER' | translate"
/>
<form #checkout="ngForm" (ngSubmit)="onSubmit(checkout)" class="checkout">
<div class="form-row">
<div id="card-info" #cardInfo></div>
<div id="card-errors" role="alert" *ngIf="error">{{ error }}</div>
</div>
<button type="submit" class="pinploy_button_v2_mobile_green">Ok</button>
</form>
</div>
</div>
index.html
<body>
<app-root></app-root>
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripeKey =
window.location.origin === "https://www.pinploy.com"
? "pk_live_******q"
: "pk_test_1P******";
let stripe = Stripe(stripeKey);
let elements = stripe.elements();
</script>
</body>
</html>

first pseudo class won't work in style components

The first pseudo class in the styled.q isn't working. It will not appear on the screen. If I copy and paste it so that ::before is listed first it doesn't work. If I list the first pseudo class a second time it works.
const ResearchingRyan = styled.div`
height: 100vw;
width: 100vw;
background-image:url(${phonePic});
background-repeat: no-repeat;
background-position: left;
background-size: cover;
display:flex;
flex-direction:column;
justify-content: flex-end;
align-items: center;
#media screen and (min-width: 525px) {
background-image:url(${tabletPic});
height: 500px;
width: 500px;
}
#media screen and (min-width: 1100px) {
background-image:url(${desktopPic});
height: 500px;
width: 500px;
}
`
const QuoteP = styled.p `
background-color:${dark};
color:${bgAlt};
padding:1rem
`
const QuoteQ=styled.q`
quotes: "\201C", "\201D";
&::after {
content: close-quote;
font-weight: bold;
font-size: 36px;
color:${bgAlt};
}
&::before {
content: open-quote;
font-weight: bold;
font-size: 36px;
color:${bgAlt};
}
`;
In "QuoteQ" component you need to correct "quotes" property. You write is correct, but sometimes in styled components meet especially work with unicode in something properties, example is "quotes".
Because of this, styles were not applied to pseudo-elements. Because style processing stopped at the quotes property. Correct the quotes and everything will work.
Below represent code with correct "quotes" property. And link to codesandbox with demo with this code.
https://codesandbox.io/s/styled-components-forked-1r1qc5
Also link to github issue with like problem.
https://github.com/styled-components/styled-components/issues/3413
const QuoteQ = styled.q`
quotes: "\\201c" "\\201d";
&::after {
content: close-quote;
font-weight: bold;
font-size: 36px;
color: blue;
}
&::before {
content: open-quote;
font-weight: bold;
font-size: 36px;
color: red;
}
`;

FlipSwitch style in Xpages

I would like to create a checkbox that looks like flipswitch.
I used this CSS classes. and I used this design elements. But I could not succeded. There is something that i missed. I do not know how to manage that?
Codes in XPages:
<div class="onoffswitch">
<xp:checkBox text="Label" id="onoffswitch"
defaultChecked="true">
<span class="onoffswitch-inner"></span> <span class="onoffswitch-switch"></span>
</xp:checkBox>
</div>
CSS Class: Resources\Style Sheets
.onoffswitch {
position: relative; width: 90px;
-webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
display: none;
}
.onoffswitch-label {
display: block; overflow: hidden; cursor: pointer;
border: 2px solid #999999; border-radius: 20px;
}
.onoffswitch-inner {
display: block; width: 200%; margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
box-sizing: border-box;
}
.onoffswitch-inner:before {
content: "ON";
padding-left: 10px;
background-color: #34A7C1; color: #FFFFFF;
}
.onoffswitch-inner:after {
content: "OFF";
padding-right: 10px;
background-color: #EEEEEE; color: #999999;
text-align: right;
}
.onoffswitch-switch {
display: block; width: 18px; margin: 6px;
background: #FFFFFF;
position: absolute; top: 0; bottom: 0;
right: 56px;
border: 2px solid #999999; border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
right: 0px;
}
I find that when you need to put markup inside a control it mostly won't work because the XPages rendering will change or ignore it. To get around this I use plain markup with a hidden control located outside of the markup. I manage the state of the hidden control with JQuery.
Here is a working example for your FlipSwitch:
<xp:checkBox text="Label" id="checkBox1"></xp:checkBox>
<div class="onoffswitch">
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch"
onclick="x$('#{id:checkBox1}').prop('checked', !(x$('#{id:checkBox1}').prop('checked')) )" />
<label class="onoffswitch-label" for="myonoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
The x$() function is a handly utility from Mark Roden:
function x$(idTag, param){ //Updated 18 Feb 2012
idTag=idTag.replace(/:/gi, "\\:")+(param ? param : "");
return($("#"+idTag));
}

Resources