We take 01 HelloReact as reference.
This example is based on the following egghead jsbin, but adding some variations.
- Rename hello.tsx file to colorpicker.tsx.
- Define properties and state.
- Create the UI.
Install Node.js and npm (v6.6.0 or newer) if they are not already installed on your computer.
Verify that you are running at least node v6.x.x and npm 3.x.x by running
node -v
andnpm -v
in a terminal/console window. Older versions may produce errors.
-
Copy the content from 01 HelloReact and execute
npm install
. -
Let's define a proper color structure (create a color.ts file).
./src/color.ts
export interface Color {
red : number;
green : number;
blue : number;
}
-
Let's rename hello.tsx to colorpicker.tsx.
-
Let's rename as well the name of the component.
import * as React from 'react';
export const ColorPicker = () => {
return (
<h2>Hello component !</h2>
);
}
- Let's create an indermediate app.tsx file as we did in some of the previous examples:
./src/app.tsx
import * as React from 'react';
import { Color } from './color';
import { ColorPicker } from './colorpicker';
interface State {
color : Color;
}
export class App extends React.Component<{}, State> {
constructor(props) {
super(props);
this.state = {color: {red: 90, green: 50, blue: 70}};
}
setColorState = (newColor : Color) => {
this.setState({color: newColor});
}
public render() {
return (
<div>
<ColorPicker/>
</div>
);
}
}
- We need to update main.tsx to adjust it to the change:
./src/main.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
- import { HelloComponent } from './hello';
+ import { App } from './app';
ReactDOM.render(
- <HelloComponent />
+ <App />,
document.getElementById('root'));
- We are going to change as well the content of the file. Let's define a color and a callback (as a property) to set the color (colorpicker.tsx).
./src/colorpicker.tsx
import * as React from 'react';
+ import { Color } from './color'
+ interface Props {
+ color : Color;
+ onColorUpdated : (color : Color) => void;
+ }
export const ColorPicker = () => {
return (
<h2>Hello component !</h2>
);
}
- Let's start by defining only one slider to control the red component of a given color (colorpicker.tsx).
./src/colorpicker.tsx
- export const ColorPicker = () => {
+ export const ColorPicker = (props : Props) => {
return (
- <h2>Hello component !</h2>
+ <div>
+ <input type="range"
+ min="0"
+ max="255"
+ value={props.color.red}
+ onChange={(event) => props.onColorUpdated(
+ {red: +event.target.value, green:
+ props.color.green, blue: props.color.blue}
+ )}
+ />
+ {props.color.red}
+ </div>
);
}
- Now it's time to update app.tsx to interact with the component's props.
./src/app.tsx
import * as React from 'react';
import { Color } from './color';
import { ColorPicker } from './colorpicker';
interface State {
color : Color;
}
export class App extends React.Component<{}, State> {
constructor(props) {
super(props);
this.state = {color: {red: 90, green: 50, blue: 70}};
}
+ setColorState = (newColor : Color) => {
+ this.setState({color: newColor});
+ }
public render() {
return (
<div>
+ <span>
+ Color: [
+ red: {this.state.color.red},
+ green: {this.state.color.green},
+ blue: {this.state.color.blue}
+ ]
+ </span>
- <ColorPicker/>
+ <ColorPicker
+ color={this.state.color}
+ onColorUpdated={this.setColorState}
+ />
</div>
);
}
}
- Let's give a try and check that we got the basics working.
npm start
- Let's complete the component by adding sliders for the green and blue options:
Note: this will look a bit ugly, in the next example we will refactor this to a cleaner solution.
./src/colopicker.tsx
export const ColorPicker = (props : Props) => {
return (
<div>
<input type="range"
min="0"
max="255"
value={props.color.red}
onChange={(event : any) => props.onColorUpdated(
{
red: event.target.value,
green: props.color.green,
blue: props.color.blue
}
)}
/>
{props.color.red}
+ <br />
+ <input type="range"
+ min="0"
+ max="255"
+ value={props.color.green}
+ onChange={(event : any) => props.onColorUpdated(
+ {
+ red: props.color.red,
+ green: +event.target.value,
+ blue: props.color.blue
+ }
+ )}
+ />
+ {props.color.green}
+ <br />
+ <input type="range"
+ min="0"
+ max="255"
+ value={props.color.blue}
+ onChange={(event : any) => props.onColorUpdated(
+ {
+ red: props.color.red,
+ green: props.color.green,
+ blue: +event.target.value
+ }
+ )}
+ />
+ {props.color.blue}
+ <br />
</div>
);
}
- Let's make this a bit more visual. It would be a good idea to display a rectangle filled with the selected color. Let's create a ColorDisplayer component (colordisplayer.tsx).
./src/colordisplayer.tsx
import * as React from 'react';
import { Color } from './color'
interface Props {
color : Color;
}
export const ColorDisplayer = (props : Props) => {
const divStyle : React.CSSProperties = { // React.CSSProperties gives editing-time visual feedback on the CSS you are typing.
width: '11rem',
height: '7rem',
backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`
};
return (
<div style={divStyle}>
</div>
);
}
- And let's use it inside our App (app.tsx) component.
import * as React from 'react';
import { Color } from './color';
import { ColorPicker } from './colorpicker';
+ import { ColorDisplayer } from './colordisplayer';
interface State {
color : Color;
}
export class App extends React.Component<{}, State> {
constructor(props) {
super(props);
this.state = {color: {red: 90, green: 50, blue: 70}};
}
setColorState(newColor : Color) {
this.setState({color: newColor});
}
public render() {
return (
<div>
+ <ColorDisplayer color={this.state.color} />
<span>
Color: [red: {this.state.color.red}, green: {this.state.color.green}, blue: {this.state.color.blue}]
</span>
<ColorPicker color={this.state.color}
onColorUpdated={this.setColorState.bind(this)}
/>
</div>
);
}
}
- Let's give a try and check the results.
npm start