From 2105301c83a052330b33e2c17ee50696095ab595 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 28 Feb 2019 09:23:27 -0800 Subject: [PATCH] Fixing the complete reducer to actually create new instance of a todo item --- step2-03/README.md | 8 ++--- step2-03/demo/src/components/TodoApp.tsx | 32 ++++++++++++++++++- step2-05/demo/src/reducers/pureFunctions.ts | 10 ++---- .../exercise/src/reducers/pureFunctions.ts | 4 +-- step2-06/demo/src/reducers/pureFunctions.ts | 7 ++-- .../exercise/src/reducers/pureFunctions.ts | 7 ++-- step2-07/demo/src/reducers/pureFunctions.ts | 7 ++-- .../exercise/src/reducers/pureFunctions.ts | 7 ++-- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/step2-03/README.md b/step2-03/README.md index 6ef59cd..cc222ac 100644 --- a/step2-03/README.md +++ b/step2-03/README.md @@ -2,7 +2,7 @@ [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. +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. 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 @@ -16,6 +16,7 @@ These are the areas that we will focus on in this step: ## Fabric Theming and Styling ### 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. @@ -65,9 +66,7 @@ loadTheme({ - 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` -## Advanced / Non-Fabric Component Styling - -### 1. CSS-in-JS with mergeStyles +### 4. CSS-in-JS with mergeStyles - `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. @@ -138,4 +137,3 @@ const className = mergeStyles({ ``` 2. Try to give a few components extra padding - diff --git a/step2-03/demo/src/components/TodoApp.tsx b/step2-03/demo/src/components/TodoApp.tsx index 6a05102..914fb03 100644 --- a/step2-03/demo/src/components/TodoApp.tsx +++ b/step2-03/demo/src/components/TodoApp.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Stack, Customizer, mergeStyles, getTheme } from 'office-ui-fabric-react'; +import { Stack, Customizer, mergeStyles, getTheme, loadTheme } from 'office-ui-fabric-react'; import { TodoFooter } from './TodoFooter'; import { TodoHeader } from './TodoHeader'; import { TodoList } from './TodoList'; @@ -13,6 +13,36 @@ const className = mergeStyles({ ...getTheme().effects.elevation4 }); +// Uncomment to see loadTheme +/* +loadTheme({ + palette: { + themePrimary: '#c41515', + themeLighterAlt: '#fdf4f4', + themeLighter: '#f6d3d3', + themeLight: '#edaeae', + themeTertiary: '#dc6666', + themeSecondary: '#cb2c2c', + themeDarkAlt: '#b11313', + themeDark: '#951010', + themeDarker: '#6e0c0c', + neutralLighterAlt: '#d5b1b1', + neutralLighter: '#d2aeae', + neutralLight: '#c9a7a7', + neutralQuaternaryAlt: '#bc9c9c', + neutralQuaternary: '#b39595', + neutralTertiaryAlt: '#ac8f8f', + neutralTertiary: '#c38c8c', + neutralSecondary: '#b06e6e', + neutralPrimaryAlt: '#9c5454', + neutralPrimary: '#500e0e', + neutralDark: '#762a2a', + black: '#621a1a', + white: '#dbb5b5' + } +}); +*/ + export class TodoApp extends React.Component { constructor(props) { super(props); diff --git a/step2-05/demo/src/reducers/pureFunctions.ts b/step2-05/demo/src/reducers/pureFunctions.ts index 40b899f..a7f98ce 100644 --- a/step2-05/demo/src/reducers/pureFunctions.ts +++ b/step2-05/demo/src/reducers/pureFunctions.ts @@ -15,13 +15,9 @@ export function remove(state: Store['todos'], id: string) { } export function complete(state: Store['todos'], id: string) { - // Clone the todos - const newTodos = { ...state }; - - // Manipulate the completed flag - newTodos[id].completed = !newTodos[id].completed; - - return newTodos; + // Clone the todo, overriding + const newTodo = { ...state[id], completed: !state[id].completed }; + return { ...state, [id]: newTodo }; } export function clear(state: Store['todos']) { diff --git a/step2-05/exercise/src/reducers/pureFunctions.ts b/step2-05/exercise/src/reducers/pureFunctions.ts index b94c02a..12ca8ef 100644 --- a/step2-05/exercise/src/reducers/pureFunctions.ts +++ b/step2-05/exercise/src/reducers/pureFunctions.ts @@ -20,8 +20,8 @@ export function remove(state: Store['todos'], id: string) { export function complete(state: Store['todos'], id: string) { // Write code: - // - to clone the state object into new state object - // - create a clone of the state[id] into a new item object + // - to clone the state[id] object into new todo object, using the spread syntax + // - in the spread syntax, also override the value of the completed key like this: {...foo, [id]: !foo[id].completed} // - modify new state and set the id key to the value of the new item object return state; diff --git a/step2-06/demo/src/reducers/pureFunctions.ts b/step2-06/demo/src/reducers/pureFunctions.ts index 792e217..e1954e5 100644 --- a/step2-06/demo/src/reducers/pureFunctions.ts +++ b/step2-06/demo/src/reducers/pureFunctions.ts @@ -13,10 +13,9 @@ export function remove(state: Store['todos'], id: string) { } export function complete(state: Store['todos'], id: string) { - const newTodos = { ...state }; - newTodos[id].completed = !newTodos[id].completed; - - return newTodos; + // Clone the todo, overriding + const newTodo = { ...state[id], completed: !state[id].completed }; + return { ...state, [id]: newTodo }; } export function clear(state: Store['todos']) { diff --git a/step2-06/exercise/src/reducers/pureFunctions.ts b/step2-06/exercise/src/reducers/pureFunctions.ts index 792e217..e1954e5 100644 --- a/step2-06/exercise/src/reducers/pureFunctions.ts +++ b/step2-06/exercise/src/reducers/pureFunctions.ts @@ -13,10 +13,9 @@ export function remove(state: Store['todos'], id: string) { } export function complete(state: Store['todos'], id: string) { - const newTodos = { ...state }; - newTodos[id].completed = !newTodos[id].completed; - - return newTodos; + // Clone the todo, overriding + const newTodo = { ...state[id], completed: !state[id].completed }; + return { ...state, [id]: newTodo }; } export function clear(state: Store['todos']) { diff --git a/step2-07/demo/src/reducers/pureFunctions.ts b/step2-07/demo/src/reducers/pureFunctions.ts index 792e217..e1954e5 100644 --- a/step2-07/demo/src/reducers/pureFunctions.ts +++ b/step2-07/demo/src/reducers/pureFunctions.ts @@ -13,10 +13,9 @@ export function remove(state: Store['todos'], id: string) { } export function complete(state: Store['todos'], id: string) { - const newTodos = { ...state }; - newTodos[id].completed = !newTodos[id].completed; - - return newTodos; + // Clone the todo, overriding + const newTodo = { ...state[id], completed: !state[id].completed }; + return { ...state, [id]: newTodo }; } export function clear(state: Store['todos']) { diff --git a/step2-07/exercise/src/reducers/pureFunctions.ts b/step2-07/exercise/src/reducers/pureFunctions.ts index 792e217..e1954e5 100644 --- a/step2-07/exercise/src/reducers/pureFunctions.ts +++ b/step2-07/exercise/src/reducers/pureFunctions.ts @@ -13,10 +13,9 @@ export function remove(state: Store['todos'], id: string) { } export function complete(state: Store['todos'], id: string) { - const newTodos = { ...state }; - newTodos[id].completed = !newTodos[id].completed; - - return newTodos; + // Clone the todo, overriding + const newTodo = { ...state[id], completed: !state[id].completed }; + return { ...state, [id]: newTodo }; } export function clear(state: Store['todos']) {