From 3fdd80f39a85c5990e37de2ad9f937ff6df4b1d3 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 28 Feb 2019 08:10:18 -0800 Subject: [PATCH 1/5] Steps 2-3 and 2-4 --- step2-03/README.md | 165 +++++++++++++++++++++--------- step2-04/README.md | 120 ++++++++++------------ step2-04/demo/src/TestMe.spec.tsx | 8 +- step2-04/demo/src/index.spec.tsx | 2 +- 4 files changed, 177 insertions(+), 118 deletions(-) diff --git a/step2-03/README.md b/step2-03/README.md index 6ef59cd..a6f58df 100644 --- a/step2-03/README.md +++ b/step2-03/README.md @@ -1,31 +1,48 @@ -# Step 2.3: Theming and Styling +# Step 2.3: Theming and styling with UI Fabric [Lessons](../) | [Exercise](./exercise/) | [Demo](./demo/) -Theming and Styling with UI Fabric. In this section, we will illustrate how to utilize some of the built-in theming and styling features right inside UI Fabric component library. +In this section, we will illustrate how to use some of the built-in theming and styling features of the UI Fabric component library. -For advanced or non-Fabric component scenarios, UI Fabric also exposes its own CSS-in-JS library called `mergeStyles` that is very performant compared with other similar libraries. A CodePen that illustrates what `mergeStyles` does: https://codepen.io/dzearing/pen/jGdgrE?editors=1011 +These are the theming and styling methods that we will focus on in this step: -These are the areas that we will focus on in this step: - -1. Theming with Fabric using `` component +1. Theming using the `` component 2. Customizing themes and loading with `loadTheme()` -3. Customizing Fabric Components `styles` prop -4. CSS-in-JS with mergeStyles +3. Customizing Fabric components via the `styles` prop +4. CSS-in-JS with `mergeStyles` -## Fabric Theming and Styling +The first three methods only work with Fabric components, but the fourth, `mergeStyles`, can be used in other projects as well. -### 1. Applying Fabric Themes -- Fabric applies themes by propagating the theme down the children through the React Context mechanism -- It is applied with the `` component -- There are some predefined themes within Fabric already, like Fluent (which will become the default in the next major), MDL2, Azure, and some other sample themes like Teams. -- Take a look at `demo/src/components/TodoApp.tsx` +## 1. Applying Fabric themes using `` -### 2. Customizing Fabric Themes +One way to apply a theme is by wrapping the components to be themed with a `` component. `Customizer` propagates the theme down to children through the [React Context](https://reactjs.org/docs/context.html) mechanism. -- Use the `loadTheme()` function to load a theme (applies to entire application): -- Erase the `` inside the `TodoApp.tsx` and place this code in the module scope. This will initialize a theme to be used throughout the application -- Fabric website has a handy theme generator to get you started with a theme: https://developer.microsoft.com/en-us/fabric#/styles/themegenerator +There are some predefined themes within Fabric already, like Fluent (which will become the default in the next major release), MDL2, Azure, and some other sample themes like Teams. + +The following code (simplified from `demo/src/components/TodoApp.tsx`) shows an example of applying the Fluent theme to our todo app using `Customizer`. + +```tsx +import { Customizer } from 'office-ui-fabric-react'; +import { FluentCustomizations } from '@uifabric/fluent-theme'; + +function render() { + return ( + + + + + + + + ); +} +``` + +## 2. Applying customized themes using `loadTheme()` + +Another way to apply a theme is using the `loadTheme()` function. Themes loaded this way apply to the entire application. + +To try out `loadTheme()` in our todo app, remove the `` tag from `TodoApp.tsx` and place this code in the module scope. ```ts import { loadTheme } from 'office-ui-fabric-react'; @@ -58,30 +75,89 @@ loadTheme({ }); ``` -### 3. Customizing One Fabric Control Instance +> If you'd like to create your own theme, the Fabric website has a [handy theme generator](https://developer.microsoft.com/en-us/fabric#/styles/themegenerator) to help get you started. -- Fabric components expose a `styles` prop (not to be confused with the React built-in one called `style`) -- You can use intellisense to discover which parts of the component you can to customize -- You can even use a style function to change the style based on some style prop -- Take a look at these customizations in `demo/src/components/TodoHeader.tsx` +## 3. Customizing one Fabric control instance -## Advanced / Non-Fabric Component Styling +If you just want to customize a single component instance's styling, Fabric components expose a `styles` prop (not to be confused with the React built-in one called `style`). -### 1. CSS-in-JS with mergeStyles +You can use intellisense to discover which parts of the component you can to customize. -- `mergeStyles` is a styling library that creates CSS class from styles that are expressed in JS. -- Fabric uses `mergeStyles` under the hood, so typically you would only directly use `mergeStyles` in niche or non-Fabric scenarios. -- These classes can be passed into `className` prop of any component like `
` -- This library replaces the need to import CSS stylesheets because they are bundled as normal JS code -- Take a look at `demo/src/components/TodoApp.tsx` +The `styles` prop can take either an object, or a function which returns a style object based on the component's prop values. + +The following code (simplified from `demo/src/components/TodoHeader.tsx`) demonstrates using `styles` to customize individual components. The TextField uses a style function and the PrimaryButton uses a style object. + +```tsx +function render() { + return ( + + + => ({ + ...(props.focused && { + field: { + backgroundColor: '#c7e0f4' + } + }) + })} + /> + + + Add + + + ); +} +``` + +## 4. CSS-in-JS with `mergeStyles` + +`mergeStyles` is a styling library that creates CSS class names from styles that are expressed as JavaScript objects. These classes can be used as the `className` prop of any component or element, such as `
`. + +This is an advanced approach which also works outside of Fabric. Within Fabric-based apps, you would typically only use `mergeStyles` in certain niche scenarios. (Fabric itself uses `mergeStyles` under the hood to power some of its styling.) + +Benefits of `mergeStyles` include: +- Works in any app +- Eliminates the need to import or bundle CSS stylesheets (all styles are bundled as normal JS code) +- Provides type checking for styles (like Sass) when used with TypeScript +- Very performant compared with other similar libraries + +The following is a basic example using mergeStyles. ([This CodePen](https://codepen.io/dzearing/pen/jGdgrE?editors=1011) illustrates in more detail what `mergeStyles` does and includes some advanced examples.) + +```tsx +// can also import from office-ui-fabric-react in Fabric-based apps +import { mergeStyles } from '@uifabric/merge-styles'; + +const blueBackgroundClassName = mergeStyles({ + backgroundColor: 'green' +}); +const className = mergeStyles(blueBackgroundClassName, { + padding: 50, // px is assumed if no units are given + selectors: { + ':hover': { + backgroundColor: 'red' + } + } +}); + +const myDiv = ( +
+ I am a green div that turns red on hover! +
+); +``` # Exercises -## Fabric Theming and Styling +## Fabric theming and styling -### Applying Fabric Themes +### Applying Fabric themes -Apply some included and predefined themes from the UI Fabric package inside the `/step2-03/exercise/src/components/TodoApp.tsx`. Do this by replacing: +Try applying some predefined themes from UI Fabric packages inside the TodoApp under `exercise/src/components/TodoApp.tsx`. Do this by replacing: ```ts import { FluentCustomizations } from '@uifabric/fluent-theme'; @@ -93,18 +169,17 @@ with: import { TeamsCustomizations } from '@uifabric/theme-samples'; ``` -### Customizing Fabric Themes +### Applying customized themes -Create your own theme and apply the color palette here: -https://developer.microsoft.com/en-us/fabric#/styles/themegenerator +1. Create your own theme using the [theme generator](https://developer.microsoft.com/en-us/fabric#/styles/themegenerator) and copy the generated code. -1. Delete the `Customizer` component +2. In `exercise/src/components/TodoApp.tsx`, delete the `Customizer` component. -2. Paste in this code in the `TodoApp.tsx` before the `TodoApp` component definition +3. Paste in the generated theme code before the `TodoApp` component definition. -3. Play around with the values and use intellisense to discover the `ITheme` type within VS Code +4. Play around with the values and use VS Code's intellisense to discover more properties of the `ITheme` type. -### Customizing One Fabric Control Instance +### Customizing one Fabric control instance 1. Open `exercise/src/components/TodoFooter.tsx` @@ -114,15 +189,11 @@ https://developer.microsoft.com/en-us/fabric#/styles/themegenerator 4. Try to customize this with a styles function -## Advanced / Non-Fabric Component Styling +## Advanced/non-Fabric component styling -### CSS in JS with MergeStyles +### CSS-in-JS with `mergeStyles` -The styling library name is neither glamorous nor does it bring about emotion, but it is very quick and lightweight. `MergeStyles` turns CSS Rules into CSS class names to be applied to the components. - -**NOTE:** Fabric components automatically use `mergeStyles` under the hood, so it is typically not necessary to directly call `mergeStyles` when styling Fabric components. - -1. Try applying a merged style `className` as a prop inside `TodoApp` +1. Try generating a class name using `mergeStyles` and use it as a `className` prop inside `TodoApp` ```tsx import { mergeStyles } from 'office-ui-fabric-react'; diff --git a/step2-04/README.md b/step2-04/README.md index b7a5afb..e1e3102 100644 --- a/step2-04/README.md +++ b/step2-04/README.md @@ -1,28 +1,27 @@ -# Step 2.4 +# Step 2.4: Testing TypeScript code with Jest [Lessons](../) | [Exercise](./exercise/) | [Demo](./demo/) -Testing TypeScript code with jest. jest is a test framework made by Facebook and is very popular in the React and the wider JS ecosystem. We will work on implementing simple unit tests here in this exercise. +[Jest](https://jestjs.io/) is a test framework made by Facebook and is very popular in the React and wider JS ecosystems. -https://jestjs.io/ +In this exercise, we will work on implementing simple unit tests using Jest. -# jest Features +## Jest Features - Multi-threaded and isolated test runner -- Provides a "fake" browser environment if needed (window, document, DOM, etc). -- Snapshots: show API or large object changes along side code changes in pull requests -- Code coverage is integrated (--coverage) -- Very clear error messages of where the test failures occur -- By default, will simulate a "good enough" browser environment called JSDOM +- Provides a fake browser-like environment if needed (window, document, DOM, etc) using jsdom +- Snapshots: Jest can create text-based snapshots of rendered components. These snapshots can be checked in and show API or large object changes alongside code changes in pull requests. +- Code coverage is integrated (`--coverage`) +- Very clear error messages showing where a test failure occurred -# How to use jest +## How to use Jest -- using `create-react-app` or other project generators, jest should already be preconfigured. Run `npm test` usually will trigger it! -- needs `jest.config.js` +- Using `create-react-app` or other project generators, Jest should already be pre-configured. Running `npm test` usually will trigger it! +- A `jest.config.js` file is used for configuration - `jsdom` might not have enough API from real browsers, for those cases, polyfills are required. Place these inside `jest.setup.js` and hook up the setup file in `jest.config.js` - in order to use `enzyme` library to test React Components, more config bits are needed inside `jest.setup.js` -# What does a test look like? +## What does a test look like? ```ts // describe(), it() and expect() are globally exported, so they don't need to be imported when jest runs these tests @@ -33,11 +32,15 @@ describe('Something to be tested', () => { }); ``` -# Test React Components by using `enzyme` +## Testing React components using Enzyme -- use `enzyme` to `mount()` the component (as oppose to rendering) -- the `mount()` function will return a wrapper that can be inspected -- the wrapper has functionality like `find()`, simulating clicks, etc. +[Enzyme](https://airbnb.io/enzyme/) is made by Airbnb and provides utilities to help test React components. + +In a real app using ReactDOM, the top-level component will be rendered on the page using `ReactDOM.render()`. Enzyme provides a lighter-weight `mount()` function which is usually adequate for testing purposes. + +`mount()` returns a wrapper that can be inspected and provides functionality like `find()`, simulating clicks, etc. + +The following code demonstrates how Enzyme can be used to help test React components. ```tsx import React from 'react'; @@ -45,19 +48,32 @@ import { mount } from 'enzyme'; import { TestMe } from './TestMe'; describe('TestMe Component', () => { - it('should have a non-clickable component when the origina InnerMe is clicked', () => { + it('should have a non-clickable component when the original InnerMe is clicked', () => { const wrapper = mount(); wrapper.find('#innerMe').simulate('click'); expect(wrapper.find('#innerMe').text()).toBe('Clicked'); }); }); + +describe('Foo Component Tests', () => { + it('allows us to set props', () => { + const wrapper = mount(); + expect(wrapper.props().bar).toBe('baz'); + wrapper.setProps({ bar: 'foo' }); + expect(wrapper.props().bar).toBe('foo'); + + wrapper.find('button').simulate('click'); + }); +}); ``` -# Advanced Topics +## Advanced topics -## Mocking +### Mocking -Mocking functions is a large part of what makes `jest` a powerful testing library. `jest` actually intercepts module inclusion process in `node.js` allowing it to mock entire modules if needed. There are many ways to mock as you can imagine in a language as flexible as JS. We only look at the simplest case but there's a lot of depth here. +Mocking functions is a large part of what makes Jest a powerful testing library. Jest actually intercepts the module loading process in Node.js, allowing it to mock entire modules if needed. + +There are many ways to mock, as you'd imagine in a language as flexible as JS. We only look at the simplest case, but there's a lot of depth here. To mock a function: @@ -66,33 +82,30 @@ it('some test function', () => { const mockCallback = jest.fn(x => 42 + x); mockCallback(1); mockCallback(2); - expect(mockCallback.mock.calls.length).toBe(2); + expect(mockCallback).toHaveBeenCalledTimes(2); }); ``` -Read more about jest mocking here: https://jestjs.io/docs/en/mock-functions.html +Read more about jest mocking [here](https://jestjs.io/docs/en/mock-functions.html). -## Async Testing +### Async Testing -### callback +For testing async scenarios, the test runner needs some way to know when the scenario is finished. Jest tests can handle async scenarios using callbacks, promises, or async/await. ```ts +// Callback it('tests callback functions', (done) => { - someFunctionThatCallsDone(done)); -}) -``` + setTimeout(() => { + done(); + }, 1000); +}); -### promise - -```ts +// Returning a promise it('tests promise functions', () => { return someFunctionThatReturnsPromise()); -}) -``` +}); -### (recommended) async / await - -```ts +// Async/await (recommended) it('tests async functions', async () => { expect(await someFunction()).toBe(5); }); @@ -100,50 +113,29 @@ it('tests async functions', async () => { # Demo -## jest basics +## Jest basics In this repo, we can start an inner loop development of tests with the command: `npm test` Take a look at code inside `demo/src`: -1. `index.ts` is exports a few functions for a counter as well as a test for squaring numbers but demonstrates out jest uses mocks +1. `index.ts` exports a few functions for a counter as well as a function for squaring numbers. We'll use this last function to demonstrate how mocks work. 2. `multiply.ts` is a contrived example of a function that is exported -3. `index.spec.ts` is the test file: note how tests are re-run on save to test file changes as well as source code changes under `src` +3. `index.spec.ts` is the test file -## testing React applications - -You can also test React Components with `jest` with the help of a partner library called `enzyme`. Take a look at the test below: - -```ts -import { mount } from 'enzyme'; - -describe('Foo Component Tests', () => { - it('allows us to set props', () => { - const wrapper = mount(); - expect(wrapper.props().bar).toBe('baz'); - wrapper.setProps({ bar: 'foo' }); - expect(wrapper.props().bar).toBe('foo'); - }); -}); -``` - -`mount` does a full mount of the component. You can use the `enzyme` wrapper to simulate clicks, etc.: - -```ts -wrapper.find('button').simulate('click'); -``` +Note how tests are re-run when either test files or source files under `src` are saved. # Exercise -## Basic Testing +## Basic testing 1. Run the tests by running `npm test` at the root of the bootcamp project -2. Look at the `stack.ts` for a sample implementation of a stack +2. Look at `exercise/src/stack.ts` for a sample implementation of a stack -3. Follow the instructions inside the `stack.spec.ts` file to complete the two tests +3. Follow the instructions inside `stack.spec.ts` file to complete the two tests ## Enzyme Testing diff --git a/step2-04/demo/src/TestMe.spec.tsx b/step2-04/demo/src/TestMe.spec.tsx index 87f7400..6fa5c3e 100644 --- a/step2-04/demo/src/TestMe.spec.tsx +++ b/step2-04/demo/src/TestMe.spec.tsx @@ -1,11 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { TestMe } from './TestMe'; -describe('TestMe Component', () => { - it('should have a non-clickable component when the origina InnerMe is clicked', () => { - const wrapper = mount(); - wrapper.find('#innerMe').simulate('click'); - expect(wrapper.find('#innerMe').text()).toBe('Clicked'); +describe('index', () => { + it('placeholder', () => { }); }); diff --git a/step2-04/demo/src/index.spec.tsx b/step2-04/demo/src/index.spec.tsx index 87f7400..70452b6 100644 --- a/step2-04/demo/src/index.spec.tsx +++ b/step2-04/demo/src/index.spec.tsx @@ -3,7 +3,7 @@ import { mount } from 'enzyme'; import { TestMe } from './TestMe'; describe('TestMe Component', () => { - it('should have a non-clickable component when the origina InnerMe is clicked', () => { + it('should have a non-clickable component when the original InnerMe is clicked', () => { const wrapper = mount(); wrapper.find('#innerMe').simulate('click'); expect(wrapper.find('#innerMe').text()).toBe('Clicked'); From 4d89fd73802bbaf78a0ac7542d6d095e7d3e31a5 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 28 Feb 2019 09:13:52 -0800 Subject: [PATCH 2/5] fix test files --- step2-04/demo/src/TestMe.spec.tsx | 6 +++++- step2-04/demo/src/index.spec.tsx | 6 +----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/step2-04/demo/src/TestMe.spec.tsx b/step2-04/demo/src/TestMe.spec.tsx index 6fa5c3e..0c5468a 100644 --- a/step2-04/demo/src/TestMe.spec.tsx +++ b/step2-04/demo/src/TestMe.spec.tsx @@ -1,7 +1,11 @@ import React from 'react'; import { mount } from 'enzyme'; +import { TestMe } from './TestMe'; describe('index', () => { - it('placeholder', () => { + it('should have a non-clickable component when the original InnerMe is clicked', () => { + const wrapper = mount(); + wrapper.find('#innerMe').simulate('click'); + expect(wrapper.find('#innerMe').text()).toBe('Clicked'); }); }); diff --git a/step2-04/demo/src/index.spec.tsx b/step2-04/demo/src/index.spec.tsx index 70452b6..3612553 100644 --- a/step2-04/demo/src/index.spec.tsx +++ b/step2-04/demo/src/index.spec.tsx @@ -1,11 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { TestMe } from './TestMe'; describe('TestMe Component', () => { - it('should have a non-clickable component when the original InnerMe is clicked', () => { - const wrapper = mount(); - wrapper.find('#innerMe').simulate('click'); - expect(wrapper.find('#innerMe').text()).toBe('Clicked'); + it('placeholder', () => { }); }); From 703a366343af21d4e989f76cfba6d2528761756c Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 28 Feb 2019 09:15:00 -0800 Subject: [PATCH 3/5] fix test names --- step2-04/demo/src/TestMe.spec.tsx | 2 +- step2-04/demo/src/index.spec.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/step2-04/demo/src/TestMe.spec.tsx b/step2-04/demo/src/TestMe.spec.tsx index 0c5468a..70452b6 100644 --- a/step2-04/demo/src/TestMe.spec.tsx +++ b/step2-04/demo/src/TestMe.spec.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { TestMe } from './TestMe'; -describe('index', () => { +describe('TestMe Component', () => { it('should have a non-clickable component when the original InnerMe is clicked', () => { const wrapper = mount(); wrapper.find('#innerMe').simulate('click'); diff --git a/step2-04/demo/src/index.spec.tsx b/step2-04/demo/src/index.spec.tsx index 3612553..6fa5c3e 100644 --- a/step2-04/demo/src/index.spec.tsx +++ b/step2-04/demo/src/index.spec.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; -describe('TestMe Component', () => { +describe('index', () => { it('placeholder', () => { }); }); From ffcb996ec3f6f04def71fc8737f702321300934c Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 28 Feb 2019 11:07:16 -0800 Subject: [PATCH 4/5] Update README.md --- step2-03/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/step2-03/README.md b/step2-03/README.md index 46043cf..baa7d09 100644 --- a/step2-03/README.md +++ b/step2-03/README.md @@ -11,7 +11,7 @@ These are the theming and styling methods that we will focus on in this step: 3. Customizing Fabric components via the `styles` prop 4. CSS-in-JS with `mergeStyles` -The first three methods only work with Fabric components, but the fourth, `mergeStyles`, can be used in other projects as well. +The first three methods only work with Fabric components, but the fourth, `mergeStyles`, can be used in other projects as well (and is typically not used within Fabric-based projects). ## 1. Applying Fabric themes using `` From 6e583f7fc00e7157dc69e4275043333f32eadb16 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 28 Feb 2019 11:37:17 -0800 Subject: [PATCH 5/5] Add step number to headers --- step1-02/exercise/index.html | 2 +- step1-02/final/index.html | 2 +- step1-03/demo/index.html | 2 +- step1-03/exercise/index.html | 2 +- step1-03/final/index.html | 2 +- step1-05/exercise/src/components/TodoHeader.tsx | 2 +- step1-05/final/src/components/TodoHeader.tsx | 2 +- step1-06/demo/src/components/TodoHeader.tsx | 2 +- step1-06/exercise/src/components/TodoHeader.tsx | 2 +- step1-06/final/src/components/TodoHeader.tsx | 2 +- step1-07/demo/src/components/TodoHeader.tsx | 2 +- step1-07/exercise/src/components/TodoHeader.tsx | 2 +- step1-07/final/src/components/TodoHeader.tsx | 2 +- step2-02/demo/src/components/TodoHeader.tsx | 2 +- step2-02/exercise/src/components/TodoHeader.tsx | 2 +- step2-03/demo/src/components/TodoHeader.tsx | 2 +- step2-03/exercise/src/components/TodoHeader.tsx | 2 +- step2-07/demo/src/components/TodoHeader.tsx | 2 +- step2-07/exercise/src/components/TodoHeader.tsx | 2 +- step2-08/demo/src/components/TodoHeader.tsx | 2 +- step2-08/exercise/src/components/TodoHeader.tsx | 2 +- step2-09/demo/src/components/TodoHeader.tsx | 2 +- step2-09/exercise/src/components/TodoHeader.tsx | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/step1-02/exercise/index.html b/step1-02/exercise/index.html index ee6a337..efdf0e5 100644 --- a/step1-02/exercise/index.html +++ b/step1-02/exercise/index.html @@ -5,7 +5,7 @@
-

todos

+

todos - step1-02 exercise

diff --git a/step1-02/final/index.html b/step1-02/final/index.html index 951b659..973212c 100644 --- a/step1-02/final/index.html +++ b/step1-02/final/index.html @@ -5,7 +5,7 @@
-

todos

+

todos - step1-02 final

diff --git a/step1-03/demo/index.html b/step1-03/demo/index.html index 19c8039..4956667 100644 --- a/step1-03/demo/index.html +++ b/step1-03/demo/index.html @@ -5,7 +5,7 @@
-

todos

+

todos - step1-03 demo

diff --git a/step1-03/exercise/index.html b/step1-03/exercise/index.html index 39816c2..aaee51a 100644 --- a/step1-03/exercise/index.html +++ b/step1-03/exercise/index.html @@ -5,7 +5,7 @@
-

todos

+

todos - step1-03 exercise

diff --git a/step1-03/final/index.html b/step1-03/final/index.html index 520bbd2..6d31d4e 100644 --- a/step1-03/final/index.html +++ b/step1-03/final/index.html @@ -5,7 +5,7 @@
-

todos

+

todos - step1-03 final

diff --git a/step1-05/exercise/src/components/TodoHeader.tsx b/step1-05/exercise/src/components/TodoHeader.tsx index 15758b7..1ff147c 100644 --- a/step1-05/exercise/src/components/TodoHeader.tsx +++ b/step1-05/exercise/src/components/TodoHeader.tsx @@ -4,7 +4,7 @@ export class TodoHeader extends React.Component { render() { return (
-

todos

+

todos - step1-05 exercise

diff --git a/step1-05/final/src/components/TodoHeader.tsx b/step1-05/final/src/components/TodoHeader.tsx index 15758b7..16d27f2 100644 --- a/step1-05/final/src/components/TodoHeader.tsx +++ b/step1-05/final/src/components/TodoHeader.tsx @@ -4,7 +4,7 @@ export class TodoHeader extends React.Component { render() { return (
-

todos

+

todos - step1-05 final

diff --git a/step1-06/demo/src/components/TodoHeader.tsx b/step1-06/demo/src/components/TodoHeader.tsx index 3209be8..dc84015 100644 --- a/step1-06/demo/src/components/TodoHeader.tsx +++ b/step1-06/demo/src/components/TodoHeader.tsx @@ -10,7 +10,7 @@ export class TodoHeader extends React.Component { const { filter } = this.props; return (
-

todos

+

todos - step1-06 demo

diff --git a/step1-06/exercise/src/components/TodoHeader.tsx b/step1-06/exercise/src/components/TodoHeader.tsx index d00d7e2..b737027 100644 --- a/step1-06/exercise/src/components/TodoHeader.tsx +++ b/step1-06/exercise/src/components/TodoHeader.tsx @@ -11,7 +11,7 @@ export class TodoHeader extends React.Component { return (
-

todos

+

todos - step1-06 exercise

diff --git a/step1-06/final/src/components/TodoHeader.tsx b/step1-06/final/src/components/TodoHeader.tsx index 4f12939..c3c9fb5 100644 --- a/step1-06/final/src/components/TodoHeader.tsx +++ b/step1-06/final/src/components/TodoHeader.tsx @@ -11,7 +11,7 @@ export class TodoHeader extends React.Component { return (
-

todos

+

todos - step1-06 final

diff --git a/step1-07/demo/src/components/TodoHeader.tsx b/step1-07/demo/src/components/TodoHeader.tsx index ff44a4e..adde668 100644 --- a/step1-07/demo/src/components/TodoHeader.tsx +++ b/step1-07/demo/src/components/TodoHeader.tsx @@ -11,7 +11,7 @@ export class TodoHeader extends React.Component { const { filter } = this.props; return (
-

todos

+

todos - step1-07 demo

diff --git a/step1-07/exercise/src/components/TodoHeader.tsx b/step1-07/exercise/src/components/TodoHeader.tsx index d5dbe48..91491f8 100644 --- a/step1-07/exercise/src/components/TodoHeader.tsx +++ b/step1-07/exercise/src/components/TodoHeader.tsx @@ -11,7 +11,7 @@ export class TodoHeader extends React.Component { const { filter } = this.props; return (
-

todos

+

todos - step1-07 exercise

diff --git a/step1-07/final/src/components/TodoHeader.tsx b/step1-07/final/src/components/TodoHeader.tsx index b3c83ea..074e30e 100644 --- a/step1-07/final/src/components/TodoHeader.tsx +++ b/step1-07/final/src/components/TodoHeader.tsx @@ -21,7 +21,7 @@ export class TodoHeader extends React.Component -

todos

+

todos - step1-07 final

diff --git a/step2-03/demo/src/components/TodoHeader.tsx b/step2-03/demo/src/components/TodoHeader.tsx index e92f9be..3e432f2 100644 --- a/step2-03/demo/src/components/TodoHeader.tsx +++ b/step2-03/demo/src/components/TodoHeader.tsx @@ -22,7 +22,7 @@ export class TodoHeader extends React.Component - todos + todos - step2-03 demo diff --git a/step2-03/exercise/src/components/TodoHeader.tsx b/step2-03/exercise/src/components/TodoHeader.tsx index 511dc1e..422675f 100644 --- a/step2-03/exercise/src/components/TodoHeader.tsx +++ b/step2-03/exercise/src/components/TodoHeader.tsx @@ -22,7 +22,7 @@ export class TodoHeader extends React.Component - todos + todos - step2-03 exercise diff --git a/step2-07/demo/src/components/TodoHeader.tsx b/step2-07/demo/src/components/TodoHeader.tsx index 56ce281..171cf06 100644 --- a/step2-07/demo/src/components/TodoHeader.tsx +++ b/step2-07/demo/src/components/TodoHeader.tsx @@ -22,7 +22,7 @@ class TodoHeader extends React.Component { return ( - todos + todos - step2-07 demo diff --git a/step2-07/exercise/src/components/TodoHeader.tsx b/step2-07/exercise/src/components/TodoHeader.tsx index ff9f329..6a410af 100644 --- a/step2-07/exercise/src/components/TodoHeader.tsx +++ b/step2-07/exercise/src/components/TodoHeader.tsx @@ -23,7 +23,7 @@ export class TodoHeader extends React.Component - todos + todos - step2-07 exercise diff --git a/step2-08/demo/src/components/TodoHeader.tsx b/step2-08/demo/src/components/TodoHeader.tsx index 280baff..ec5b351 100644 --- a/step2-08/demo/src/components/TodoHeader.tsx +++ b/step2-08/demo/src/components/TodoHeader.tsx @@ -24,7 +24,7 @@ class TodoHeader extends React.Component { return ( - todos + todos - step2-08 demo diff --git a/step2-08/exercise/src/components/TodoHeader.tsx b/step2-08/exercise/src/components/TodoHeader.tsx index 04e9aab..c0de11c 100644 --- a/step2-08/exercise/src/components/TodoHeader.tsx +++ b/step2-08/exercise/src/components/TodoHeader.tsx @@ -24,7 +24,7 @@ class TodoHeader extends React.Component { return ( - todos + todos - step2-08 exercise diff --git a/step2-09/demo/src/components/TodoHeader.tsx b/step2-09/demo/src/components/TodoHeader.tsx index d2c0b7e..943a6d0 100644 --- a/step2-09/demo/src/components/TodoHeader.tsx +++ b/step2-09/demo/src/components/TodoHeader.tsx @@ -24,7 +24,7 @@ class TodoHeader extends React.Component { return ( - todos + todos - step2-09 demo diff --git a/step2-09/exercise/src/components/TodoHeader.tsx b/step2-09/exercise/src/components/TodoHeader.tsx index d2c0b7e..c885b88 100644 --- a/step2-09/exercise/src/components/TodoHeader.tsx +++ b/step2-09/exercise/src/components/TodoHeader.tsx @@ -24,7 +24,7 @@ class TodoHeader extends React.Component { return ( - todos + todos - step2-09 exercise