I'm working with treebeard in my react project.
when I try to add a user-defined style it's not getting applied to the container.
I have tried different methods to achieve this.
I tried to define the style from tag, tried to define style.css in a different file, import it and assign it to style in Treedeard tag.
the main goal is to change the background color and the position.
Here is my code:
workspace.jsx
import React from "react";
import {Treebeard} from 'react-treebeard';
import data from "./data";
export class WorkSpace extends React. Component {
constructor(props){
super(props);
this.state = {
data: {data}
};
this.onToggle = this.onToggle.bind(this);
const decorators = {
Container: (props) => {
return (
<div style={props.backgroundColor="yellow"}>
</div>
);
}
};
}
onToggle(node, toggled){
const {cursor, data} = this.state.data;
if (cursor) {
this.setState(() => ({cursor, active: false}));
}
node.active = true;
if (node.children) {
node.toggled = toggled;
}
this.setState(() => ({cursor: node, data: Object.assign({}, data)}));
}
render() {
return (
<div className="base_container">
<h3>Select Component</h3>
<div className="components">
<Treebeard
data={data}
onToggle={this.onToggle}
style = {style_components}
decorators={this.decorators}
/>
</div>
</div>
);
}
}
Related
I want to scale only one element in the map when clicking on the picture. I read that I have to use an index but I don't know how to do it. I also saw how to do it in inline "onclick" by passing index there. But I want to do it with separated function.
Here is the code :
import './App.css';
import { useSelector, useDispatch } from 'react-redux';
import { useEffect, useState } from 'react';
import { birds, mountains,trees, search } from './features/slices/photoSlice';
function App() {
const url = useSelector((state)=>state.url)
const dispatch = useDispatch()
const [photos, setPhoto] = useState('')
const [scale, setScale] = useState(false)
const [photoindex, setPhotoindex] = useState(0)
useEffect(()=>{
fetch(url).then(res=>res.json()).then(data=>setPhoto(data))
},[url])
const handleSearch = (e) =>{
if(e.key==='Enter'){
e.preventDefault()
dispatch(search(e.target.value))
}
}
const handleClickOnPicture = (e) => {
if(e){
setScale(!scale)
}
}
return (
<div className="App">
// Problem is here below:
{photos?photos.hits.map((photo, index)=>{
return <img className={scale?'m-5 h-80 scale-125':'m-5 h-80'} onClick={handleClickOnPicture} key={photo.webformatURL} src={photo.webformatURL}/>
}):""}
</div>
</div>
</div>
);
}
export default App;
I removed half of the code, so you will see only the problem.
use event.target.classname to add/remove classes
const handleClickOnPicture = (e) => {
if(!e.target.classList.contains('scale-125')){
e.target.classList.add('scale-125')
}
else{
e.target.classList.remove('scale-125')
}
}
<img className='m-5 h-80' onClick={handleClickOnPicture} key={photo.webformatURL} src={photo.webformatURL}/>
I have two Stencil components. MyCard and MyButton.
MyButton.tsx
import { Component, h, Prop } from '#stencil/core';
#Component({
tag: 'my-button',
styleUrl: 'my-button.css',
shadow: true,
})
export class MyButton {
#Prop() label: string;
render() {
return (
<div>
<button>
{this.label}
</button>
</div>
);
}
}
MyButton.stories.ts
const Template = (args) => `<my-button label="${args.label}"></my-button>`;
export const Example = Template.bind({});
Example.args = {
label: 'my custom button'
}
MyCard.tsx
import { Component, h, Prop } from '#stencil/core';
#Component({
tag: 'my-card',
styleUrls: ['my-card.scss'],
shadow: true,
})
export class MyCard {
render() {
return (
<div>
<div>
<my-button></my-button>
</div>
</div>
)
}
}
MyCard.stories.ts
const MyCardDefault = (args) => (
`<my-card>
<my-button label="${args.label}"></my-button>
</my-card>`
)
export const CardExample = MyCardDefault.bind({});
CardExample.args = {
label: "CardButton"
}
If I open the MyButton component in Storybook, the args are properly passed, and the label is applied to the button, but when I open the MyCard component, the button innerHTML is empty. The props are not passed. Why? How do I pass props to a nested child component in Stencil?
I don't know Storybook, but your MyCard component does not have any properties and does not set any properties on it's my-button element, so binding a label to the card won't do anything because MyCard doesn't use the label. I think you need:
export class MyCard {
#Prop() label: string;
render() {
return (
<div>
<div>
<my-button label={this.label}></my-button>
</div>
</div>
)
}
}
To demonstrate a component I try to write custom state and methods for a story.
For example, I have a component ListItems who accepts an array of string as Input.
In the story of this component I want to show an interactive example of the usage of this component.
So my story will have internal state "items" and internal method "addItem"
I know how to do that with React, but I'm stuck with Angular.
Here is a React way to do that:
(View in codesandbox)
// ListItems.tsx
import React from "react";
export type ListItemsProps = { items: string[] };
export const ListItems = ({ items = [] }: ListItemsProps) => {
return (
<ul>
{items.map((item, key) => (
<li key={key}>{item}</li>
))}
</ul>
);
};
// ListItems.stories.tsx
import React, { useState } from "react";
import { ListItems } from "./ListItems";
export default {
title: "ListItems",
component: ListItems
};
export const Text = () => {
const [items, setItems] = useState(["Demo Item"]);
const [value, setValue] = useState("");
const addItem = () => {
setItems([...items, value]);
setValue("");
};
return (
<div>
<ListItems items={items} />
<input value={value} onChange={(e) => setValue(e.target.value)} />
<input type="submit" onClick={addItem} value="add" />
</div>
);
};
};
How can I write the same story with following Angular Component ?
import { Component, OnInit, Input } from "#angular/core";
#Component({
selector: "app-list-items",
template: `<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>`
})
export default class ListItems implements OnInit {
#Input() items: string[] = [];
constructor(){}
ngOnInit(): void {}
}
Finally I found a solution on Angular, but it's not an elegant one...
Maybe someone know a better way !
And I can't find a solution to show the code story template on "Show code" feature.
import { Story, Meta } from '#storybook/angular/types-6-0';
import { ListItemsComponent } from './list-items.component';
import { Component } from '#angular/core';
export default {
title: 'Demo/ListItems',
component: ListItemsComponent,
} as Meta;
const Template: Story<ListItemsComponent> = (args: ListItemsComponent) => ({
props:args,
});
export const BasicDemo = Template.bind({})
BasicDemo.args={
items: ["Basic Demo", "Without interaction"]
}
// Create a dedicated component for the interactive story
#Component({
selector: 'story-list-items',
template: `
<core-list-items [items]="items"></core-list-items>
<input type="text" [(ngModel)]="value" /><button (click)="addItem()">add</button>
`,
})
class InteractiveDemoComponent{
items = [];
value: string = '';
addItem(){
this.items = [...this.items, this.value];
this.value = ""
}
}
const InteractiveTemplate: Story<ListItemsComponent> = (args: ListItemsComponent) => ({
props:args,
component: InteractiveDemoComponent,
});
export const InteractiveDemo = InteractiveTemplate.bind({});
InteractiveDemo.args = {
items: ["Interactive Demo"]
}
I have a react component where I am trying to change the background color of the css when clicking the div.
I know you can set the color in the component, but I am using this component many times, and don't to make multiple component files with just a different color, and even if I did, I am curious besides the fact.
How can I access (or even console.log to figure it out on my own) the css file and its properties through the component? Thanks ahead of time.
If you want to keep all background-color styles in your .css/.scss file, you will need to have a good className strategy to link the styles to your components. Here is my suggestion:
styles.scss
.blue {
background-color: blue;
&.clicked {
background-color: red;
}
}
Container.js
import React from 'react';
import ClickableDiv from './ClickableDiv.js';
const Container = () => (
<ClickableDiv className="blue">
<p>This is my text.</p>
</ClickableDiv>
);
export default Container;
ClickableDiv.js
import React, { Component } from 'react';
class ClickableDiv extends Component {
constructor() {
super();
this.state = { clicked: false };
this.handleDivClick = this.handleDivClick.bind(this);
}
handleDivClick() {
this.setState({ clicked: true });
}
render() {
const divClassName = [this.props.classname];
if (this.state.clicked) divClassName.push('clicked');
return (
<div className={divClassName.join(' ').trim()} onClick={this.handleDivClick}>
{this.props.children}
</div>
);
}
}
export default ClickableDiv;
Rendered Markup
Unclicked:
<div class="blue"><p>This is my text.</p></div>
Clicked:
<div class="blue clicked"><p>This is my text.</p></div>
You can pass in the desired background color as a prop, and use internal state with an onClick handler.
Container.js
import React from 'react';
import ClickableDiv from './ClickableDiv';
const Container = () => (
<ClickableDiv backgroundColor="#FF0000">
<p>This is my text.</p>
</ClickableDiv>
);
export default Container;
ClickableDiv.js
import React, { Component } from 'react';
class ClickableDiv extends Component {
constructor() {
super();
this.state = {};
this.handleDivClick = this.handleDivClick.bind(this);
}
handleDivClick() {
const { backgroundColor } = this.props;
if (backgroundColor) this.setState({ backgroundColor });
}
render() {
const { backgroundColor } = this.state;
return (
<div style={{ backgroundColor }} onClick={this.handleDivClick}>
{this.props.children}
</div>
);
}
}
export default ClickableDiv;
Better to make an external css file and write your css code in that file and just import that one in index.html
At which point in a React components life cycle can I get the components css properties which are set in a css file?
I've tried it in the render method and the componentDidMount method and neither assigned the css properties to the component.
export default class HomeArtist extends React.Component {
constructor(props){
super(props);
}
componentDidMount(){
let ImageStore = document.getElementsByClassName('home-artist-display');
console.log("ComponentDidMount: ", ImageStore);
}
render(){
var ImageStyle = {
backgroundImage: "url("+this.props.info.image+")"
};
return (
<div className="home-artist-display" style={ImageStyle}>
<Link to={"artist/" + this.props.info.id}>
<h3 className="home-artist-name">{this.props.info.name}</h3>
</Link>
</div>
)
}
}
I wrote a React library that exposes a size object (with width and height props) to components.
For your use case you could use it like so:
import SizeMe from 'react-sizeme'; // import me!
class HomeArtist extends React.Component {
...
render(){
// Size gets passed in as props!
const { width, height } = this.props.size;
var ImageStyle = {
backgroundImage: "url("+this.props.info.image+")"
};
return (
<div className="home-artist-display" style={ImageStyle}>
<Link to={"artist/" + this.props.info.id}>
<h3 className="home-artist-name">{this.props.info.name}</h3>
</Link>
</div>
)
}
}
// wrap your component export!
export default SizeMe()(HomeArtist);
--
You can find out full details at https://github.com/ctrlplusb/react-sizeme