I would like to create a circle as a custom component in Backendless. Here's my code in bundle.js
define(() => {
return function CustomComponent() {
return React.createElement('div',{
className:'test',
height: '125px',
width: '125px',
style:{
background: '#bbb',
display: 'inline-block',
border-radius: '50%',
}
})
}
});
But it doesn't work and I'm getting: Can not render page due to error: "Cannot read properties of undefined (reading 'default')"
Related
I'm trying to define the font size for h elements in a Chakra-UI theme, and for some reason, no matter what I do it's not overriding what I'm assuming is the base theme responsive definitions.
This is in NextJS, pulling content from DatoCMS headless CMS, so the actual instantiation of the h elements looks like this:
...
renderRule(isHeading, ({ node, children, key }) => {
return (
<Heading key={key} as={`h${node.level}`} pt={6} pb={4}>
{children}
</Heading>
);
}),
...
If I change it there to, say, <Heading key={key} as={`h${node.level}\`} pt={6} pb={4} size=('5xl')>, it works fine. My theme also works fine in general (e.g., naming brand color variables, setting the font weight on Heading elements), but for some reason, I can't get it to set the size of the headings.
The closest I've gotten is setting the size in the global object:
const styles = {
global: (props) => ({
h1: { fontSize: [null, null, '5xl'] }
})
}
Doing the above at least makes it to the browser, but it gets overridden. In dev tools, the computed css shows
#media screen and (min-width: 48em)
.css-fcs9e9 {
font-size: var(--chakra-fontSizes-4xl);
line-height: 1.2;
}
.css-fcs9e9 {
font-family: var(--chakra-fonts-heading);
font-weight: var(--chakra-fontWeights-light);
// font-size: var(--chakra-fontSizes-3xl); shown as overridden
line-height: 1.33;
padding-top: var(--chakra-space-6);
padding-bottom: var(--chakra-space-4);
}
#media screen and (min-width: 48em)
h1 {
// font-size: var(--chakra-fontSizes-5xl); shown as overridden
}
I've also tried
setting a single value in textStyles:
const textStyles = {
h1: {
fontSize: '5xl'
}
}
setting an array in textStyles:
const textStyles = {
h1: {
fontSize: [ null, null, '5xl' ]
}
}
setting the baseStyle at the component level:
const Heading = defineStyleConfig({
baseStyle: {
fontWeight: 'light', // this works
textStyles: { h1: [ null, null, '5xl' ] } // this doesn't work (also for singular `textStyle`
}
})
but none of those three even make it to the browser.
What's the right way to set the text size at the theme level?
Have a following sample of code which I want migrate to vanilla-extract, my main question is how to generate styles for style attribute in this case?
// in ColorToken.tsx
function ColorToken(props: { name: string; value?: string }) {
return (
<div
style={{
backgroundColor: `var(${props.value})`,
border: 'solid 1px var(--color-border-neutral)',
borderRadius: '100%',
width: '70px',
height: '70px',
}}
>
{props.name}
</div>
);
}
I tried two approaches:
First
// ColorToken.css.ts
import { style } from '#vanilla-extract/css';
export function colorSelector(bgColor: string) {
return style({
backgroundColor: bgColor,
border: 'solid 1px var(--color-border-neutral)',
borderRadius: '100%',
width: '70px',
height: '70px',
});
}
// ColorToken.tsx
import * as selectors from './Colors.css';
function ColorToken(props: { name: string; value?: string }) {
const color: string = // dynamically piking color based on props.
return (
<div className={selectors.colorSelector(color)}>
Error / issue:
error - ./pages/styles/tokens/Colors.css.ts
Error: Invalid exports.
You can only export plain objects, arrays, strings, numbers and null/undefined.
at Array.map (<anonymous>)
Second
// ColorToken.css.ts
export const colorSelector = {
border: 'solid 1px var(--color-border-neutral)',
borderRadius: '100%',
width: '70px',
height: '70px',
};
// ColorToken.tsx
import { style } from '#vanilla-extract/css';
import * as selectors from './Colors.css';
function ColorToken(props: { name: string; value?: string }) {
const color: string = // dynamically piking color based on props.
return (
<div className={style({ ...selectors.colorSelector, backgroundColor: color })}>
Note: here I'm using style function because I think VE might apply some extra things (e.g add vendor prefixes, optimizations etc).
Error / issue:
Unhandled Runtime Error
Error: Styles were unable to be assigned to a file. This is generally caused by one of the following:
- You may have created styles outside of a '.css.ts' context
- You may have incorrect configuration. See https://vanilla-extract.style/documentation/setup
Note: using VE via NextJS setup.
The key to keep in mind here is that vanilla works at build time. It outputs a plain CSS stylesheet, so trying to substitute values in at runtime isn't what it's built for.
If you have a clearly defined set of background colours that you want to use, you could use a recipe, or you could start to build up some atomic CSS with sprinkles.
If it needs to be truly dynamic, impossible to know at build time, you can take advantage of CSS variables using vanilla's dynamic package.
Good evening everyone, I need some help.
I can't solve a warning:
Keyframes.js:20 The component styled.p with the id of "sc-iseJRi" has
been created dynamically. You may see this warning because you've
called styled inside another component. To resolve this only create
new StyledComponents outside of any render method and function
component.
In this link ( https://pastebin.com/a0kMztfD ) is an example of how I use the styled-component.
In a checkboxes file I have all the functions I use for the styled-component rules, which I then call in the App.js file to assign them to a const variable to use in the return()
How could I solve this problem? It doesn't create any errors for me but of course it creates a thousand warnings.
I also put the code in addition to the link put previously:
In cards.js:
export function getCard(Card) {
let fillMode = (Card.style === null) ? 'both' : Card.style.fillMode
let duration = (Card.style === null) ? '1s' : Card.style.duration
const tmp = keyframes`
from,to {
width: ${Card.width};
height: ${Card.height};
background-color: ${Card.colorCard};
background: linear-gradient(${Card.colorCard2}, ${Card.colorCard});
box-shadow: 0 16px 16px -8px rgba(0,0,0,0.4);
border-radius: 6px;
overflow: hidden;
position: relative;
margin: ${Card.marginCard};
}
`;
const CardFinal = styled.div`
animation: ${duration} ${tmp} ${fillMode};
`;
return CardFinal
}
In App.js:
Const CardContainer = getCard(card1)
return (
<CardContainer></CardContainer>
);
The problem is that you're creating a styled.div inside your getCard function.
The way you get rid of this warning is to move the creation of CardFinal outside of getCard and use getCard function to return whatever css you want to generate and pass them as props later on. Here's how you can pass props with styled-components.
This is how it would look like for your code
const CardFinal = styled.div`
${getAnimation}
`;
export function getCardProps(Card) {
const fillMode = Card.style === null ? "both" : Card.style.fillMode;
const duration = Card.style === null ? "1s" : Card.style.duration;
const tmp = keyframes`
from,to {
width: ${Card.width};
height: ${Card.height};
background-color: ${Card.colorCard};
background: linear-gradient(${Card.colorCard2}, ${Card.colorCard});
box-shadow: 0 16px 16px -8px rgba(0,0,0,0.4);
border-radius: 6px;
overflow: hidden;
position: relative;
margin: ${Card.marginCard};
}
`;
return { fillMode, duration, tmp };
}
const getAnimation = ({ duration, tmp, fillMode }) => {
return css`
animation: ${duration} ${tmp} ${fillMode};
`;
};
Now you'll just use the getCardProps function to the props that CardFinal expects from the getCardProps.
export default function App() {
const cardProps = getCardProps({
style: null,
weight: "100px",
height: "100px",
colorCard: "grey",
marginCard: "10px"
});
return (
<CardFinal {...cardProps}>
YO
</CardFinal>
);
}
Here's a codesandbox link of where you can try & play around to see how it works.
You can also try to un-comment a // const WarningDiv, that basically replicates the warnings you've been encountering with just a basic function that returns an empty styled.div
i don't know what difference in this code.
class a is component and example is example.js
import React, {Component} from 'react';
const styles = {
border: {
display: 'inline-block',
height: '19px',
padding: '1px 8px 0',
border: '2px solid',
borderRadius: '12px',
lineHeight: '20px',
fontSize: '14px',
verticalAlign: 'top',
},
default: {
display: 'inline-block',
height: '20px',
padding: '1px 10px 0',
borderRadius: '10px',
lineHeight: '21px',
fontSize: '13px',
verticalAlign: 'top',
},
state: {
display: 'inline-block',
width: '14px',
height: '13px',
paddingTop: '1px',
lineHeight: '14px',
fontSize: '11px',
color: '#fff',
letterSpacing: '-0.5px',
textAlign: 'center',
verticalAlign: 'top',
}
};
class A extends Component {
static defaultProps = {
type: 'default',
};
render() {
const {
label,
style,
type,
...other
} = this.props;
switch (type) {
case 'border':
elementStyle = styles.border;
break;
case 'default':
elementStyle = styles.default;
break;
case 'state':
elementStyle = styles.state;
break;
}
return (
<span style={Object.assign(elementStyle, style)} {...other}>{label}</span>
);
}
}
export default A;
and example code is example.js
import A from './A';
export default class Example extends React.Component {
render() {
return (
<div>
<A style={{background: '#fe6969', color: '#fff'}} />
<A style={{background: '#ff8137', color: '#fff'}} />
<A style={{background: '#fcb400', color: '#fff'}} />
</div>
);
}
}
this code error is Uncaught TypeError: Cannot assign to read only property 'background' of object '#'
i use babel-loader 8, babel7 ,webpack4
if i correct Object.assgin({}, elementStyle, style) is working.
i think this error occur when rerendering A component.
i don't know why this error...
please help me.
All you need to do is concat/merge two objects like this using spread
{{...elementStyle, ...style}} or
{Object.assign({}, elementStyle , style) }
You should understand the nature of how Object.assign works. It returns the target object as the return value of its operation.
So, in the first syntax:
Object.assign({}, elementStyle , style)
you are creating a brand new object with the enumerable properties of elementStyle and style.
If you do this:
Object.assign(elementStyle, style)
Then elementStyle itself is the target object, so that will be mutated and that will be what is returned from Object.assign.
Here is an example what I mean.
Example 1 :
// With no new target object
const original = [{id:1}, {id:2}, {id:3}];
const newArray = original.map(elem => {
return Object.assign(elem, {id:2});
});
console.log('Original object has changed');
console.log(original);
//------------------------------
// With a new target object
const original2 = [{id:1}, {id:2}, {id:3}];
const newArray2 = original2.map(elem => {
return Object.assign({}, elem, {id:2});
});
console.log('Original object has not changed');
console.log(original2);
Example 2 :
var styles = {
circle: {backgroundColor: 'yellow', height: '1005', width: '100%'},
circleA: {backgroundColor: 'blue'},
};
So we need all circle to have default cir some circle style, but we need to change some property,
// background yellow
<div style={styles.circle}></div>
// background blue
<div style={Object.assign(styles.circle, styles.circleA)}></div>
// expeted background yellow, but it's blue. cus styles.circle still have it's merged value
<div style={styles.circle}></div>
The solution is to pass an empty object to Object.assign(). By doing this, you're telling the method to produce a NEW object with the objects you pass it.
Example 3:
const obj1 = {
name: "J"
}
const obj2 = {
gander: "m"
}
// Here, obj1 is the same after the Object.assign call
console.log(Object.assign({}, obj1, obj2));
console.log(obj1)
console.log(obj2)
console.log("without empty obj passed")
// Note that after this call, obj1 holds both keys. So this will mutate it:
console.log(Object.assign(obj1, obj2));
console.log(obj1) // This is different now
console.log(obj2)
In your case,
`<A propstyle={{background: '#fe6969', color: '#fff'}} />
<A propstyle={{background: '#ff8137', color: '#fff'}} /> `
component A defined twice in Parent, which means that we will get two circles and child component will render twice.
and in Child component you defined like below:
<span style={Object.assign(elementStyle , style) }{...other}>{label}</span>
first render :
Object.assign overwrite properties from right to left props style to elementStyle,here elementStyle itself is the target object,that will be what is returned from Object.assign.
style props : { background: "#fe6969", color: "#fff" }
elementStyle : { background: "#fe6969", borderRadius: "10px", color: "#fff" }
Second render :
Object.assign tries to overwrite properties from right to left, but elementStyle have { background: "#fe6969", borderRadius: "10px", color: "#fff" }
and Object.assign is still in loop (remember example 1 .map())
style props : { background: "#ff8137", color: "#fff" }
error thrown: 'TypeError: Cannot assign to read only property 'background' of object ' when {Object.assign(elementStyle , style) } because there's no new target object.
please find the full code here
Hope it helps. read more
Instead of assigning values directly to the object, clone the object first instead of mutating an object that is immutable due to the fact that the object is a props object or because Object.defineproperties was used to set writable to "false", but just clone the object and assign the values to the cloned object and use the cloned object, but assign the values to the cloned object properly as well.
Instead of assigning and mutating directly like:
object.field = value
Do:
let clonedObject = {...object}
clonedObject = {...clonedObject, field: value}
Otherwise using object.defineproperties to set the writable property to "true" might also be another way that would work.
Object.defineProperty(object, 'field1', {
value: 1,
writable: true
});
I'm using React Select v2 in my project with Styled Components and I need to be able to turn the arrow indicator upside down when the menu is open, which was supported in v1.
I kinda managed to do it by doing this:
css`
&.react-select__control--is-focused {
& .react-select__indicators {
& .react-select__dropdown-indicator {
transform: rotate(180deg);
}
}
}
`;
Problem is that, if I press the arrow to open the menu and click on it again to close it, the arrow stays upside down because the select is still focused, which feels a bit weird in terms of UIX.
Is there a proper way to rotate it based on the state of the menu? I looked for something in the documentation but I couldn't find it.
Maybe I missed it, if someone could point me in the right direction, that'd be awesome!
Thanks!
Technically you can use the style-in-JS props of the v2. Like the following example:
dropdownIndicator: (base, state) => ({
...base,
transition: 'all .2s ease',
transform: state.isFocused ? 'rotate(180deg)' : null
})
It seems that the isFocused state isn't bind with the isMenuOpen state but with the real focus state of the container.
A solution is to set closeMenuOnSelect={false} so the user would have to click outside the select and your arrow will flip back.
Or you could change the className props using onMenuOpen and onMenuClose by adding a specific suffix to target your animation.
UPDATE
You can directly access the menuOpen props via the state so no need to manually add class like the following:
dropdownIndicator: (base, state) => ({
...base,
transition: 'all .2s ease',
transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : null
})
PLEASE NOTE THAT
In react-select v2.3 a control--menu-is-open has been added directly in the code.
This worked for me
<select styles={{
dropdownIndicator: (provided, state) => ({
...provided,
transform: state.selectProps.menuIsOpen && "rotate(180deg)"
})
}}
/>
So, based on Laura's response, my solution was to use the onMenuClose and onMenuOpen to set the state of a property in my styled component.
const indicatorStyle = (props: StyledSelectProps & DropdownProps<{}>) => css`
& .react-select__indicators {
& .react-select__dropdown-indicator {
transition: all .2s ease;
transform: ${props.isOpen && "rotate(180deg)"};
}
}
`;
This function is called inside of my styled component's css.
And then in the component I call my styled component, I control the state:
export class Dropdown<TValue> extends React.Component<DropdownProps<TValue>> {
public state = { isOpen: false };
private onMenuOpen = () => this.setState({ isOpen: true });
private onMenuClose = () => this.setState({ isOpen: false });
public render() {
const { ...props } = this.props;
const { isOpen } = this.state;
return (
<StyledSelect {...props} isOpen={isOpen} onMenuOpen={this.onMenuOpen} onMenuClose={this.onMenuClose} />
);
}
}
A bit convoluted but it works for now.
This worked for me.
dropdownIndicator: (base, state) => ({
...base,
transform: state.selectProps.menuIsOpen ? 'rotate(-90deg)' : 'rotate(0)',
transition: '250ms',
}),
i solved this issue like this.
mostly you have to play arround with these in your css to do stuff on certain conditions
--is-focused
--menu-is-open
--is-disabled
--is-selected
styled component css
.paginatorPageSizeCustomSelectPreffix__indicator {
svg {
color: var(--black);
height: 18px;
width: 18px;
transform: rotate(180deg);
transition: 0.2s;
}
}
.paginatorPageSizeCustomSelectPreffix__control--menu-is-open {
.paginatorPageSizeCustomSelectPreffix__indicator {
svg {
color: var(--black);
height: 18px;
width: 18px;
transform: rotate(360deg);
transition: 0.2s;
}
}
}
}