├── .gitattributes
├── 9781484270516.jpg
├── Contributing.md
├── LICENSE.txt
├── README.md
├── ch01
└── react-d3-hello-world
│ ├── README.md
│ ├── README_CRA.md
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── HelloD3
│ │ │ ├── HelloD3.scss
│ │ │ ├── HelloD3.test.tsx
│ │ │ └── HelloD3.tsx
│ │ ├── HelloD3Class
│ │ │ ├── HelloD3Class.scss
│ │ │ ├── HelloD3Class.test.tsx
│ │ │ └── HelloD3Class.tsx
│ │ └── README
│ ├── features
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ └── README
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ └── setupTests.ts
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ └── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ ├── tsconfig.json
│ └── yarn.lock
├── ch02
├── README.md
├── README_CRA.md
├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
├── generate-react-cli.json
├── jest-puppeteer.config.js
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── .DS_Store
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── CircleWithEvents
│ │ │ ├── CircleWithD3Events.tsx
│ │ │ ├── CircleWithEvents.scss
│ │ │ └── CircleWithEvents.tsx
│ │ ├── HelloD3
│ │ │ ├── HelloD3.scss
│ │ │ ├── HelloD3.test.tsx
│ │ │ └── HelloD3.tsx
│ │ ├── HelloD3Class
│ │ │ ├── HelloD3Class.scss
│ │ │ ├── HelloD3Class.test.tsx
│ │ │ └── HelloD3Class.tsx
│ │ ├── HelloD3Data
│ │ │ ├── HelloD3Data.scss
│ │ │ ├── HelloD3Data.test.tsx
│ │ │ └── HelloD3Data.tsx
│ │ ├── HelloJSXData
│ │ │ ├── HelloJSXData.scss
│ │ │ ├── HelloJSXData.test.tsx
│ │ │ └── HelloJSXData.tsx
│ │ ├── HelloSVG
│ │ │ ├── HelloSVG.scss
│ │ │ ├── HelloSVG.test.tsx
│ │ │ └── HelloSVG.tsx
│ │ ├── JSXCanvas
│ │ │ ├── JSXCanvas.scss
│ │ │ ├── JSXCanvas.test.tsx
│ │ │ └── JSXCanvas.tsx
│ │ ├── PulsatingCircle
│ │ │ ├── PulsatingCircle.tsx
│ │ │ └── PulsatingCircleD3.tsx
│ │ ├── README
│ │ └── SimpleChart
│ │ │ ├── SimpleChart.scss
│ │ │ ├── SimpleChart.test.tsx
│ │ │ └── SimpleChart.tsx
│ ├── features
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ └── README
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ └── setupTests.ts
├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ └── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
├── tsconfig.json
└── yarn.lock
├── ch03
├── README.md
├── README_CRA.md
├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
├── generate-react-cli.json
├── jest-puppeteer.config.js
├── package.json
├── public
│ ├── data
│ │ ├── area.csv
│ │ ├── bar.csv
│ │ ├── line.csv
│ │ ├── pie.csv
│ │ └── scatter.csv
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── BasicAreaChart
│ │ │ ├── BasicAreaChart.scss
│ │ │ ├── BasicAreaChart.test.tsx
│ │ │ ├── BasicAreaChart.tsx
│ │ │ └── types.ts
│ │ ├── BasicBarChart
│ │ │ ├── BasicBarChart.scss
│ │ │ ├── BasicBarChart.test.tsx
│ │ │ ├── BasicBarChart.tsx
│ │ │ └── types.ts
│ │ ├── BasicDonutChart
│ │ │ ├── BasicDonutChart.tsx
│ │ │ └── types.ts
│ │ ├── BasicLineChart
│ │ │ ├── BasicLineChart.scss
│ │ │ ├── BasicLineChart.test.tsx
│ │ │ ├── BasicLineChart.tsx
│ │ │ └── types.ts
│ │ ├── BasicPieChart
│ │ │ ├── BasicPieChart.scss
│ │ │ ├── BasicPieChart.test.tsx
│ │ │ ├── BasicPieChart.tsx
│ │ │ └── types.ts
│ │ ├── BasicScatterChart
│ │ │ ├── BasicScatterChart.scss
│ │ │ ├── BasicScatterChart.test.tsx
│ │ │ ├── BasicScatterChart.tsx
│ │ │ └── types.ts
│ │ └── README
│ ├── features
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ └── README
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ └── setupTests.ts
├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ └── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
└── tsconfig.json
├── ch04-05
└── histogram-d3-ts
│ ├── .env
│ ├── .eslintignore
│ ├── .eslintrc
│ ├── .gitignore
│ ├── .prettierrc
│ ├── README.md
│ ├── README_CRA.md
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── data
│ │ ├── README
│ │ └── historicalPrice.csv
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── Histogram
│ │ │ ├── Histogram.scss
│ │ │ ├── Histogram.test.tsx
│ │ │ ├── Histogram.tsx
│ │ │ └── types.ts
│ │ ├── PriceTableList
│ │ │ ├── PriceTableList.scss
│ │ │ ├── PriceTableList.test.tsx
│ │ │ ├── PriceTableList.tsx
│ │ │ └── types.ts
│ │ └── README
│ ├── features
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ ├── README
│ │ ├── historicalPriceObject.ts
│ │ └── index.ts
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ ├── README
│ │ │ └── historicalPriceAtoms.ts
│ │ └── selectors
│ │ │ ├── README
│ │ │ └── historicalPriceSelectors.ts
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ ├── HistogramWidget
│ │ ├── HistogramWidget.scss
│ │ ├── HistogramWidget.test.tsx
│ │ └── HistogramWidget.tsx
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ ├── templates
│ │ ├── component
│ │ │ ├── component.js
│ │ │ ├── component.tsx
│ │ │ ├── style.scss
│ │ │ ├── test.js
│ │ │ └── test.tsx
│ │ ├── d3
│ │ │ └── component.tsx
│ │ ├── d3class
│ │ │ └── component.tsx
│ │ ├── materialui
│ │ │ └── materialui.tsx
│ │ ├── page
│ │ │ ├── component.tsx
│ │ │ ├── style.scss
│ │ │ └── test.tsx
│ │ ├── recoil
│ │ │ ├── component.tsx
│ │ │ └── test.tsx
│ │ └── widget
│ │ │ └── Widget.tsx
│ └── widget
│ │ └── Widget.tsx
│ └── tsconfig.json
├── ch06
└── world-map-chart
│ ├── README.md
│ ├── README_CRA.md
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── data
│ │ ├── coordinates.csv
│ │ └── world-110m.json
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── README
│ │ └── WorldMap
│ │ │ ├── RotatingRoundWorldMap.tsx
│ │ │ ├── RotatingRoundWorldMapWithCoordinates.tsx
│ │ │ ├── RoundWorldMap.tsx
│ │ │ ├── WorldMap.scss
│ │ │ ├── WorldMap.test.tsx
│ │ │ ├── WorldMap.tsx
│ │ │ ├── WorldMapAtlas.tsx
│ │ │ └── types.tsx
│ ├── features
│ │ └── README
│ ├── hooks
│ │ ├── AnimationFrame.tsx
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ └── README
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ └── widget
│ │ └── Widget.tsx
│ ├── tsconfig.json
│ └── yarn.lock
├── ch07
└── world-map-widget
│ ├── README.md
│ ├── README_CRA.md
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── clients-logo
│ │ ├── Allocadia.png
│ │ ├── CiaoBellaGelato.png
│ │ ├── EsteeLauder.png
│ │ ├── KickApps.png
│ │ ├── MTV.png
│ │ ├── MotionBox.png
│ │ ├── NBC.png
│ │ ├── README
│ │ ├── RockSoul.png
│ │ ├── UPMC.png
│ │ ├── Vitaminwater.png
│ │ ├── WeightWatchers.png
│ │ ├── att.png
│ │ ├── chatand.png
│ │ ├── digitallyspeaking.png
│ │ ├── friesens.png
│ │ ├── gantto.png
│ │ ├── gdconf.png
│ │ ├── hbo.png
│ │ ├── iheart.png
│ │ ├── monbijouparis.png
│ │ ├── ritani.png
│ │ └── surgiview.png
│ ├── data
│ │ ├── client-list.csv
│ │ └── world-110m.json
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ ├── README
│ │ └── about
│ │ │ └── EliEladElrom.jpg
│ ├── components
│ │ ├── ClientList
│ │ │ ├── ClientList.scss
│ │ │ ├── ClientList.test.tsx
│ │ │ └── ClientList.tsx
│ │ ├── ClientListDetail
│ │ │ ├── ClientListDetail.scss
│ │ │ ├── ClientListDetail.test.tsx
│ │ │ └── ClientListDetail.tsx
│ │ ├── PulsatingCircle
│ │ │ ├── PulsatingCircle.scss
│ │ │ ├── PulsatingCircle.test.tsx
│ │ │ └── PulsatingCircle.tsx
│ │ ├── README
│ │ └── WorldMap
│ │ │ ├── WorldMap.scss
│ │ │ ├── WorldMap.test.tsx
│ │ │ ├── WorldMap.tsx
│ │ │ └── types.tsx
│ ├── features
│ │ └── README
│ ├── hooks
│ │ ├── AnimationFrame.tsx
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ ├── README
│ │ ├── clientsObject.ts
│ │ ├── index.ts
│ │ └── mapObject.ts
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ ├── README
│ │ │ ├── clientsSelectors.ts
│ │ │ └── mapSelectors.ts
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ ├── ClientsWidget
│ │ ├── ClientsWidget.scss
│ │ ├── ClientsWidget.test.tsx
│ │ └── ClientsWidget.tsx
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ └── widget
│ │ └── Widget.tsx
│ ├── tsconfig.json
│ └── yarn.lock
├── ch08
└── bubble-chart
│ ├── .env
│ ├── .eslintignore
│ ├── .eslintrc
│ ├── .gitignore
│ ├── .prettierrc
│ ├── README.md
│ ├── README_CRA.md
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── BubbleChart
│ │ │ ├── BubbleChart.scss
│ │ │ ├── BubbleChart.test.tsx
│ │ │ ├── BubbleChart.tsx
│ │ │ ├── BubbleChartWithAnimation.tsx
│ │ │ └── types.tsx
│ │ └── README
│ ├── features
│ │ └── README
│ ├── hooks
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ └── README
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ └── widget
│ │ └── Widget.tsx
│ └── tsconfig.json
├── ch09
└── force-chart
│ ├── README.md
│ ├── README_CRA.md
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── data
│ │ └── power_network.json
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── README
│ │ └── SimpleForceGraph
│ │ │ ├── Circle.tsx
│ │ │ ├── Circles.tsx
│ │ │ ├── Label.tsx
│ │ │ ├── Labels.tsx
│ │ │ ├── Link.tsx
│ │ │ ├── Links.tsx
│ │ │ ├── SimpleForceGraph.scss
│ │ │ ├── SimpleForceGraph.tsx
│ │ │ └── types.ts
│ ├── features
│ │ └── README
│ ├── hooks
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ ├── README
│ │ │ └── powerChartSelectors.ts
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ ├── NetworksWidget
│ │ ├── NetworksWidget.scss
│ │ └── NetworksWidget.tsx
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ └── widget
│ │ └── Widget.tsx
│ ├── tsconfig.json
│ └── yarn.lock
├── ch10
└── react-chart-libraries
│ ├── README.md
│ ├── README_CRA.md
│ ├── build
│ ├── asset-manifest.json
│ ├── data
│ │ ├── area.csv
│ │ ├── bar.csv
│ │ ├── calendar.json
│ │ ├── line.csv
│ │ ├── pie.csv
│ │ └── scatter.csv
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ ├── precache-manifest.d31aea694f13a98c79a18199b156b1b0.js
│ ├── report.html
│ ├── robots.txt
│ ├── service-worker.js
│ └── static
│ │ ├── css
│ │ ├── 2.5a2f7233.chunk.css
│ │ ├── 2.5a2f7233.chunk.css.map
│ │ ├── main.7a4fb01d.chunk.css
│ │ └── main.7a4fb01d.chunk.css.map
│ │ └── js
│ │ ├── 2.d6ebf2ae.chunk.js
│ │ ├── 2.d6ebf2ae.chunk.js.LICENSE.txt
│ │ ├── 2.d6ebf2ae.chunk.js.map
│ │ ├── main.b4acb14e.chunk.js
│ │ ├── main.b4acb14e.chunk.js.map
│ │ ├── runtime-main.e2745115.js
│ │ └── runtime-main.e2745115.js.map
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── data
│ │ ├── area.csv
│ │ ├── bar.csv
│ │ ├── calendar.json
│ │ ├── line.csv
│ │ ├── pie.csv
│ │ └── scatter.csv
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── README
│ │ ├── SimpleBarGraph
│ │ │ └── SimpleBarGraph.tsx
│ │ ├── SimpleCalendarChart
│ │ │ └── SimpleCalendarChart.tsx
│ │ ├── SimpleLineChart
│ │ │ ├── SimpleLineChart.tsx
│ │ │ └── types.ts
│ │ ├── SimplePie
│ │ │ └── SimplePie.tsx
│ │ └── SimpleReactVizChart
│ │ │ └── SimpleReactVizChart.tsx
│ ├── features
│ │ └── README
│ ├── hooks
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ ├── README
│ │ │ ├── calendarDataSelectors.ts
│ │ │ └── lineDataSelectors.ts
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ └── widget
│ │ └── Widget.tsx
│ ├── tsconfig.json
│ ├── yarn-error.log
│ └── yarn.lock
├── ch11
└── knick-knacks
│ ├── README.md
│ ├── README_CRA.md
│ ├── build
│ ├── 200.html
│ ├── 404.html
│ ├── Rectangle
│ │ └── index.html
│ ├── asset-manifest.json
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ ├── precache-manifest.c3bcfa4a722d25579c0220494ee6f547.js
│ ├── robots.txt
│ ├── service-worker.js
│ └── static
│ │ ├── css
│ │ ├── main.5c815069.chunk.css
│ │ └── main.5c815069.chunk.css.map
│ │ └── js
│ │ ├── 2.d9a1b4ed.chunk.js
│ │ ├── 2.d9a1b4ed.chunk.js.LICENSE.txt
│ │ ├── 2.d9a1b4ed.chunk.js.map
│ │ ├── 3.ff43eb1d.chunk.js
│ │ ├── 3.ff43eb1d.chunk.js.map
│ │ ├── main.f0d19790.chunk.js
│ │ ├── main.f0d19790.chunk.js.map
│ │ ├── runtime-main.efe5e15b.js
│ │ └── runtime-main.efe5e15b.js.map
│ ├── e2e
│ ├── app.test.tsx
│ ├── global.d.ts
│ ├── jest.config.js
│ └── puppeteer_standalone.js
│ ├── generate-react-cli.json
│ ├── jest-puppeteer.config.js
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ ├── src
│ ├── App.scss
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── AppRouter.test.tsx
│ ├── AppRouter.tsx
│ ├── assets
│ │ └── README
│ ├── components
│ │ ├── HelloD3Data
│ │ │ ├── HelloD3Data.tsx
│ │ │ └── HelloD3DataCloned.tsx
│ │ ├── HelloD3DataClass
│ │ │ └── HelloD3DataClass.tsx
│ │ ├── README
│ │ └── Rectangle
│ │ │ └── Rectangle.tsx
│ ├── features
│ │ └── README
│ ├── hooks
│ │ └── README
│ ├── index.scss
│ ├── index.tsx
│ ├── layout
│ │ └── README
│ ├── logo.svg
│ ├── model
│ │ └── README
│ ├── pages
│ │ └── README
│ ├── react-app-env.d.ts
│ ├── recoil
│ │ ├── atoms
│ │ │ └── README
│ │ └── selectors
│ │ │ └── README
│ ├── redux
│ │ └── store.ts
│ ├── serviceWorker.ts
│ ├── setupTests.ts
│ └── widgets
│ │ └── README
│ ├── templates
│ ├── component
│ │ ├── component.js
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ ├── test.js
│ │ └── test.tsx
│ ├── d3
│ │ └── component.tsx
│ ├── d3class
│ │ └── component.tsx
│ ├── materialui
│ │ └── materialui.tsx
│ ├── page
│ │ ├── component.tsx
│ │ ├── style.scss
│ │ └── test.tsx
│ ├── recoil
│ │ ├── component.tsx
│ │ └── test.tsx
│ └── widget
│ │ └── Widget.tsx
│ ├── tsconfig.json
│ ├── yarn-error.log
│ └── yarn.lock
├── ch12
└── nextjs-ts-chart
│ ├── .gitignore
│ ├── README.md
│ ├── next-env.d.ts
│ ├── package.json
│ ├── server.js
│ ├── tsconfig.json
│ └── yarn.lock
└── errata.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/9781484270516.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/9781484270516.jpg
--------------------------------------------------------------------------------
/Contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing to Apress Source Code
2 |
3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers.
4 |
5 | ## How to Contribute
6 |
7 | 1. Make sure you have a GitHub account.
8 | 2. Fork the repository for the relevant book.
9 | 3. Create a new branch on which to make your change, e.g.
10 | `git checkout -b my_code_contribution`
11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted.
12 | 5. Submit a pull request.
13 |
14 | Thank you for your contribution!
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch01/react-d3-hello-world/public/favicon.ico
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch01/react-d3-hello-world/public/logo192.png
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch01/react-d3-hello-world/public/logo512.png
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import './App.scss'
3 | import HelloD3 from './components/HelloD3/HelloD3'
4 |
5 | function App() {
6 | return (
7 |
8 |
11 |
12 | )
13 | }
14 |
15 | export default App
16 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/components/HelloD3/HelloD3.scss:
--------------------------------------------------------------------------------
1 | .HelloD3 {
2 | }
3 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/components/HelloD3/HelloD3.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloD3/HelloD3.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloD3 from './HelloD3'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/components/HelloD3Class/HelloD3Class.scss:
--------------------------------------------------------------------------------
1 | .HelloD3Class {
2 | }
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/components/HelloD3Class/HelloD3Class.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloD3Class/HelloD3Class.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloD3Class from './HelloD3Class'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/components/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch01/react-d3-hello-world/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch02/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch02/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch02/e2e/puppeteer_standalone.js:
--------------------------------------------------------------------------------
1 | const puppeteer = require('puppeteer');
2 | const SERVER_URL = 'http://localhost:3000';
3 |
4 | (async function main(){
5 | try {
6 | const browser = await puppeteer.launch({ headless: false });
7 | const page = await browser.newPage();
8 | await page.goto(SERVER_URL, {waitUntil: 'domcontentloaded'});
9 |
10 | const urlLink = await page.$('a[href*="https://github.com"]');
11 | if (urlLink) {
12 | await urlLink.click();
13 | } else {
14 | console.log('No "urlLink" found on page');
15 | }
16 | // wait 2 secs and shut down!
17 | await new Promise(resolve => setTimeout(resolve, 2000));
18 | await browser.close();
19 | } catch (error) {
20 | if (error.message.includes('ERR_CONNECTION_REFUSED'))
21 | console.log('Make sure you have React running: $ yarn start');
22 | console.log('Error message', error.message);
23 | }
24 | })();
--------------------------------------------------------------------------------
/ch02/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch02/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch02/public/favicon.ico
--------------------------------------------------------------------------------
/ch02/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch02/public/logo192.png
--------------------------------------------------------------------------------
/ch02/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch02/public/logo512.png
--------------------------------------------------------------------------------
/ch02/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch02/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch02/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch02/src/.DS_Store
--------------------------------------------------------------------------------
/ch02/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch02/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch02/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch02/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch02/src/components/CircleWithEvents/CircleWithEvents.scss:
--------------------------------------------------------------------------------
1 | .circle {
2 | cursor: pointer;
3 | width: 150px;
4 | height: 150px;
5 | fill: #6666;
6 | }
7 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3/HelloD3.scss:
--------------------------------------------------------------------------------
1 | .HelloD3 {
2 | }
3 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3/HelloD3.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloD3/HelloD3.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloD3 from './HelloD3'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3Class/HelloD3Class.scss:
--------------------------------------------------------------------------------
1 | .HelloD3Class {
2 | }
3 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3Class/HelloD3Class.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloD3Class/HelloD3Class.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloD3Class from './HelloD3Class'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3Data/HelloD3Data.scss:
--------------------------------------------------------------------------------
1 | .HelloD3Data {
2 | }
3 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3Data/HelloD3Data.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloD3Data/HelloD3Data.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloD3Data from './HelloD3Data'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloD3Data/HelloD3Data.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloD3Data/HelloD3Data.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './HelloD3Data.scss'
10 | import * as d3 from 'd3' // yarn add d3 @types/d3
11 |
12 | const HelloD3Data = (props: IHelloD3DataProps) => {
13 | useEffect(() => {
14 | draw()
15 | })
16 |
17 | const draw = () => {
18 | d3.select('.HelloD3Data')
19 | .selectAll('p')
20 | .data(props.data)
21 | .enter()
22 | .append('p')
23 | .text((d) => `d3 ${d}`)
24 | }
25 |
26 | return
27 | }
28 |
29 | interface IHelloD3DataProps {
30 | data: string[]
31 | }
32 |
33 | export default HelloD3Data
34 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloJSXData/HelloJSXData.scss:
--------------------------------------------------------------------------------
1 | .HelloJSXData {
2 | }
3 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloJSXData/HelloJSXData.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloJSXData/HelloJSXData.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloJSXData from './HelloJSXData'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloJSXData/HelloJSXData.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloJSXData/HelloJSXData.tsx
6 | */
7 |
8 | import React from 'react'
9 | import './HelloJSXData.scss'
10 |
11 | const HelloJSXData = (props: IHelloJSXDataProps) => {
12 | return (
13 |
14 | {props.data.map((d, index) => (
15 |
jsx {d}
16 | ))}
17 |
18 | )
19 | }
20 |
21 | interface IHelloJSXDataProps {
22 | data: string[]
23 | }
24 |
25 | export default HelloJSXData
26 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloSVG/HelloSVG.scss:
--------------------------------------------------------------------------------
1 | .myRect {
2 | fill: #ba2121;
3 | }
4 |
--------------------------------------------------------------------------------
/ch02/src/components/HelloSVG/HelloSVG.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/HelloSVG/HelloSVG.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import HelloSVG from './HelloSVG'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/components/JSXCanvas/JSXCanvas.scss:
--------------------------------------------------------------------------------
1 | .JSXCanvas {
2 | }
3 |
--------------------------------------------------------------------------------
/ch02/src/components/JSXCanvas/JSXCanvas.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/JSXCanvas/JSXCanvas.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import JSXCanvas from './JSXCanvas'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/components/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
--------------------------------------------------------------------------------
/ch02/src/components/SimpleChart/SimpleChart.scss:
--------------------------------------------------------------------------------
1 | .SimpleChart {
2 | }
3 |
--------------------------------------------------------------------------------
/ch02/src/components/SimpleChart/SimpleChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/SimpleChart/SimpleChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import SimpleChart from './SimpleChart'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch02/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch02/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch02/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch02/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch02/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch02/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch02/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch02/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch02/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch02/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch02/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch02/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch02/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch02/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch02/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch03/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch03/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch03/e2e/puppeteer_standalone.js:
--------------------------------------------------------------------------------
1 | const puppeteer = require('puppeteer');
2 | const SERVER_URL = 'http://localhost:3000';
3 |
4 | (async function main(){
5 | try {
6 | const browser = await puppeteer.launch({ headless: false });
7 | const page = await browser.newPage();
8 | await page.goto(SERVER_URL, {waitUntil: 'domcontentloaded'});
9 |
10 | const urlLink = await page.$('a[href*="https://github.com"]');
11 | if (urlLink) {
12 | await urlLink.click();
13 | } else {
14 | console.log('No "urlLink" found on page');
15 | }
16 | // wait 2 secs and shut down!
17 | await new Promise(resolve => setTimeout(resolve, 2000));
18 | await browser.close();
19 | } catch (error) {
20 | if (error.message.includes('ERR_CONNECTION_REFUSED'))
21 | console.log('Make sure you have React running: $ yarn start');
22 | console.log('Error message', error.message);
23 | }
24 | })();
--------------------------------------------------------------------------------
/ch03/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch03/public/data/bar.csv:
--------------------------------------------------------------------------------
1 | framework,carat
2 | jQuery,43.3
3 | React.js,35.9
4 | Angular,25.1
5 | ASP.NET,21.9
6 | Express,21.2
7 | .NET Core,19.1
8 | Vue.js,17.3
9 | Spring,16.4
10 | Angular.js,16.1
11 | Django,14.2
12 | Flask,14.2
13 | Laravel,11.1
14 | Rails,7.0
15 | Symfony,14.4
16 | Gatsby, 4.0
17 | Drupal, 3.2
--------------------------------------------------------------------------------
/ch03/public/data/pie.csv:
--------------------------------------------------------------------------------
1 | name,value
2 | a,25
3 | b,3
4 | c,45
5 | d,7
6 | e,20
--------------------------------------------------------------------------------
/ch03/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch03/public/favicon.ico
--------------------------------------------------------------------------------
/ch03/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch03/public/logo192.png
--------------------------------------------------------------------------------
/ch03/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch03/public/logo512.png
--------------------------------------------------------------------------------
/ch03/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch03/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch03/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch03/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch03/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch03/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch03/src/components/BasicAreaChart/BasicAreaChart.scss:
--------------------------------------------------------------------------------
1 | .basicBarChart {
2 | }
3 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicAreaChart/BasicAreaChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicAreaChart/BasicAreaChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import BasicAreaChart from './BasicAreaChart'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicAreaChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicAreaChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | // eslint-disable-next-line @typescript-eslint/naming-convention
10 | export type data = {
11 | date: string
12 | value: number
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicBarChart/BasicBarChart.scss:
--------------------------------------------------------------------------------
1 | .basicBarChart {
2 | }
3 |
4 | .bar {
5 | fill: tomato;
6 | }
7 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicBarChart/BasicBarChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicBarChart/BasicBarChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import BasicBarChart from './BasicBarChart'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicBarChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicBarChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | framework: string
11 | value: number
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicDonutChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicDonutChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | name: string
11 | value: number
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicLineChart/BasicLineChart.scss:
--------------------------------------------------------------------------------
1 | .basicLineChart {
2 | }
3 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicLineChart/BasicLineChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicLineChart/BasicLineChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import BasicLineChart from './BasicLineChart'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicLineChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicLineChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | date: string
11 | value: number
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicPieChart/BasicPieChart.scss:
--------------------------------------------------------------------------------
1 | .basicPieChart {
2 | }
3 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicPieChart/BasicPieChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicPieChart/BasicPieChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import BasicPieChart from './BasicPieChart'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicPieChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicPieChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | name: string
11 | value: number
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicScatterChart/BasicScatterChart.scss:
--------------------------------------------------------------------------------
1 | .basicScatterChart {
2 | }
3 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicScatterChart/BasicScatterChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicScatterChart/BasicScatterChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import BasicScatterChart from './BasicScatterChart'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch03/src/components/BasicScatterChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicScatterChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | price: number
11 | carat: number
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch03/src/components/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
--------------------------------------------------------------------------------
/ch03/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch03/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch03/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch03/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch03/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch03/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch03/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch03/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch03/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch03/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch03/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch03/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch03/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch03/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch03/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch03/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
2 | BROWSER=none
3 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*
2 | public/*
3 | docs/*
4 | templates/*
5 | src/react-app-env.d.ts
6 | src/serviceWorker.ts
7 | e2e/jest.config.js
8 | e2e/puppeteer_standalone.js
9 | jest-puppeteer.config.js
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/.gitignore:
--------------------------------------------------------------------------------
1 | # misc
2 | .DS_Store
3 | package-lock.json
4 | yarn-error.log
5 | yarn.lock
6 | docs
7 |
8 | # IDEs
9 | .vscode
10 | .idea
11 |
12 | # dependencies
13 | /node_modules
14 | /.pnp
15 | .pnp.js
16 |
17 | # testing
18 | /coverage
19 | .nyc_output
20 |
21 | # production
22 | /build
23 |
24 | # misc
25 | .DS_Store
26 | .env.local
27 | .env.development.local
28 | .env.test.local
29 | .env.production.local
30 |
31 | npm-debug.log*
32 | yarn-debug.log*
33 | yarn-error.log*
34 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "printWidth": 200,
4 | "semi": false,
5 | "singleQuote": true,
6 | "tabWidth": 2
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/public/data/README:
--------------------------------------------------------------------------------
1 | Date source:
2 | https://ethereumprice.org/history/?start=2020-01-01&end=2020-12-12¤cy=USD
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch04-05/histogram-d3-ts/public/favicon.ico
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch04-05/histogram-d3-ts/public/logo192.png
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch04-05/histogram-d3-ts/public/logo512.png
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/Histogram/Histogram.scss:
--------------------------------------------------------------------------------
1 | .histogram {
2 | padding-top: 50px;
3 | }
4 | .sliderDiv {
5 | width: 400px;
6 | padding-left: 50px;
7 | padding-top: 20px;
8 | }
9 | svg text {
10 | fill: white;
11 | }
12 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/Histogram/Histogram.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/Histogram/Histogram.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import Histogram from './Histogram'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow(
18 |
19 |
20 |
21 | )
22 | })
23 |
24 | test('It should mount', () => {
25 | expect(component.length).toBe(1)
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/Histogram/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/Histogram/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | price: number
11 | }
12 | export type BarsNode = {
13 | x0: number
14 | x1: number
15 | length: number
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/PriceTableList/PriceTableList.scss:
--------------------------------------------------------------------------------
1 | .priceTableListTableCellHead {
2 | background-color: #343434;
3 | }
4 |
5 | .priceTableListTableCell {
6 | background-color: #515151;
7 | }
8 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/PriceTableList/PriceTableList.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/PriceTableList/PriceTableList.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import PriceTableList from './PriceTableList'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/PriceTableList/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/PriceTableList/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | price: number
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/components/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/model/historicalPriceObject.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/model/historicalPriceObject.ts
6 | */
7 |
8 | // eslint-disable-next-line @typescript-eslint/naming-convention
9 | export interface historicalPriceObject {
10 | price: number
11 | }
12 |
13 | export const initHistoricalPrice = (): historicalPriceObject => ({
14 | price: 0,
15 | })
16 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/model/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/model/index.ts
6 | */
7 |
8 | export * from './historicalPriceObject'
9 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/recoil/atoms/historicalPriceAtoms.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/recoil/atoms/historicalPriceAtoms.ts
6 | */
7 |
8 | import { atom } from 'recoil'
9 | import { initHistoricalPrice } from '../../model'
10 |
11 | export const historicalPriceState = atom({
12 | key: 'historicalPriceState',
13 | default: initHistoricalPrice(),
14 | })
15 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/recoil/selectors/historicalPriceSelectors.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/model/historicalPriceSelectors.ts
6 | */
7 |
8 | import { selector } from 'recoil'
9 | import * as d3 from 'd3'
10 |
11 | import { historicalPriceObject } from '../../model'
12 |
13 | export const getHistoricalPriceData = selector({
14 | key: 'getHistoricalPriceData',
15 | get: async () => {
16 | return getData()
17 | },
18 | })
19 |
20 | const getData = () =>
21 | new Promise((resolve) =>
22 | d3
23 | .dsv(',', '/data/historicalPrice.csv', function results(d) {
24 | return {
25 | price: d.open,
26 | }
27 | })
28 | .then(function results(data) {
29 | resolve((data as unknown) as historicalPriceObject[])
30 | })
31 | )
32 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/widgets/HistogramWidget/HistogramWidget.scss:
--------------------------------------------------------------------------------
1 | .priceTableListDivWrapper {
2 | padding-top: 100px;
3 | width: 500px;
4 | height: 500px;
5 | }
6 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/widgets/HistogramWidget/HistogramWidget.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/widgets/HistogramWidget/HistogramWidget.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import HistogramWidget from './HistogramWidget'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow(
18 |
19 |
20 |
21 | )
22 | })
23 |
24 | test('It should mount', () => {
25 | expect(component.length).toBe(1)
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/templates/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch04-05/histogram-d3-ts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch06/world-map-chart/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch06/world-map-chart/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/public/data/coordinates.csv:
--------------------------------------------------------------------------------
1 | id,latitude,longitude
2 | 1,-73.9919,40.7529
3 | 2,-70.0007884457405,40.75509010847814
4 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch06/world-map-chart/public/favicon.ico
--------------------------------------------------------------------------------
/ch06/world-map-chart/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch06/world-map-chart/public/logo192.png
--------------------------------------------------------------------------------
/ch06/world-map-chart/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch06/world-map-chart/public/logo512.png
--------------------------------------------------------------------------------
/ch06/world-map-chart/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #ffffff;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/components/README:
--------------------------------------------------------------------------------
1 | Components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/components/WorldMap/WorldMap.scss:
--------------------------------------------------------------------------------
1 | .WorldMap {
2 | }
3 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/components/WorldMap/WorldMap.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/WorldMap/WorldMap.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import WorldMapAtlas from './WorldMapAtlas'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | })
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/components/WorldMap/types.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicScatterChart/types.ts
6 | */
7 |
8 | import { Feature, Geometry } from 'geojson'
9 |
10 | export namespace Types {
11 | export type CoordinatesData = {
12 | id: number
13 | latitude: number
14 | longitude: number
15 | }
16 |
17 | export type MapObject = {
18 | mapFeatures: Array>
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/hooks/README:
--------------------------------------------------------------------------------
1 | Hooks goes here. Check out some hooks examples here:
2 | https://github.com/EliEladElrom/react-tutorials
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch06/world-map-chart/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch06/world-map-chart/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch06/world-map-chart/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch06/world-map-chart/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch07/world-map-widget/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch07/world-map-widget/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/Allocadia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/Allocadia.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/CiaoBellaGelato.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/CiaoBellaGelato.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/EsteeLauder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/EsteeLauder.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/KickApps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/KickApps.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/MTV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/MTV.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/MotionBox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/MotionBox.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/NBC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/NBC.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/README:
--------------------------------------------------------------------------------
1 | LOGOs goes here
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/RockSoul.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/RockSoul.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/UPMC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/UPMC.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/Vitaminwater.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/Vitaminwater.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/WeightWatchers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/WeightWatchers.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/att.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/att.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/chatand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/chatand.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/digitallyspeaking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/digitallyspeaking.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/friesens.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/friesens.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/gantto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/gantto.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/gdconf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/gdconf.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/hbo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/hbo.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/iheart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/iheart.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/monbijouparis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/monbijouparis.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/ritani.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/ritani.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/clients-logo/surgiview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/clients-logo/surgiview.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/data/client-list.csv:
--------------------------------------------------------------------------------
1 | id,name,logo,description,address,city,state,country,latitude,longitude,website
2 | 1,Company,company.png,description,address,New York,NY,USA,-70,40,https://company.com/
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/favicon.ico
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/logo192.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/public/logo512.png
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #ffffff;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/App.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/App.tsx
6 | */
7 |
8 | import React from 'react'
9 | import './App.scss'
10 | import ClientsWidget from './widgets/ClientsWidget/ClientsWidget'
11 |
12 | function App() {
13 | return (
14 |
15 |
18 |
19 | )
20 | }
21 |
22 | export default App
23 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/assets/about/EliEladElrom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch07/world-map-widget/src/assets/about/EliEladElrom.jpg
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/ClientList/ClientList.scss:
--------------------------------------------------------------------------------
1 | .ClientList {
2 | }
3 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/ClientList/ClientList.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/ClientList/ClientList.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import ClientList from './ClientList'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow(
18 |
19 |
20 |
21 | )
22 | })
23 |
24 | test('It should mount', () => {
25 | expect(component.length).toBe(1)
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/ClientListDetail/ClientListDetail.scss:
--------------------------------------------------------------------------------
1 | .ClientListDetail {
2 | }
3 |
4 | .about-image {
5 | padding-left: 20px;
6 | padding-right: 20px;
7 | width: 100px;
8 | -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
9 | filter: grayscale(100%);
10 | }
11 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/ClientListDetail/ClientListDetail.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/ClientListDetail/ClientListDetail.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import ClientListDetail from './ClientListDetail'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow(
18 |
19 |
20 |
21 | )
22 | })
23 |
24 | test('It should mount', () => {
25 | expect(component.length).toBe(1)
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/PulsatingCircle/PulsatingCircle.scss:
--------------------------------------------------------------------------------
1 | .PulsatingCircle {
2 | }
3 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/PulsatingCircle/PulsatingCircle.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { shallow } from 'enzyme'
3 | import PulsatingCircle from './PulsatingCircle'
4 |
5 | describe('', () => {
6 | let component
7 |
8 | beforeEach(() => {
9 | component = shallow()
10 | })
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/README:
--------------------------------------------------------------------------------
1 | Components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/WorldMap/WorldMap.scss:
--------------------------------------------------------------------------------
1 | .WorldMap {
2 | }
3 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/components/WorldMap/types.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BasicScatterChart/types.ts
6 | */
7 |
8 | import { Feature, Geometry } from 'geojson'
9 |
10 | export namespace Types {
11 | export type ClientData = {
12 | id: number
13 | latitude: number
14 | longitude: number
15 | name: string
16 | logo: string
17 | description: string
18 | address: string
19 | city: string
20 | state: string
21 | country: string
22 | website: string
23 | }
24 |
25 | export type MapObject = {
26 | mapFeatures: Array>
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/hooks/README:
--------------------------------------------------------------------------------
1 | Hooks goes here. Check out some hooks examples here:
2 | https://github.com/EliEladElrom/react-tutorials
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/model/clientsObject.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/model/clientsObject.ts
6 | */
7 |
8 | // eslint-disable-next-line @typescript-eslint/naming-convention
9 | export interface clientsObject {
10 | id: number
11 | latitude: number
12 | longitude: number
13 | name: string
14 | logo: string
15 | description: string
16 | address: string
17 | city: string
18 | state: string
19 | country: string
20 | website: string
21 | }
22 |
23 | export const initClientsObject = (): clientsObject => ({
24 | id: -1,
25 | latitude: 0,
26 | longitude: 0,
27 | name: '',
28 | logo: '',
29 | description: '',
30 | address: '',
31 | city: '',
32 | state: '',
33 | country: '',
34 | website: '',
35 | })
36 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/model/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/model/index.ts
6 | */
7 |
8 | export * from './mapObject'
9 | export * from './clientsObject'
10 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/model/mapObject.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/model/mapObject.ts
6 | */
7 |
8 | import { Feature, Geometry } from 'geojson'
9 |
10 | // eslint-disable-next-line @typescript-eslint/naming-convention
11 | export interface mapObject {
12 | mapFeatures: Array>
13 | }
14 |
15 | export const initMapObject = (): mapObject => ({
16 | mapFeatures: Array>(),
17 | })
18 |
19 | export const setMapObject = (data: Array>): mapObject => ({
20 | mapFeatures: data,
21 | })
22 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/recoil/selectors/clientsSelectors.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/recoil/selectors/clientsSelectors.ts
6 | */
7 |
8 | import { selector } from 'recoil'
9 | import * as d3 from 'd3'
10 |
11 | import { clientsObject } from '../../model'
12 |
13 | export const getPreviousClientListData = selector({
14 | key: 'GetPreviousClientListData',
15 | get: async () => {
16 | return getData()
17 | },
18 | })
19 |
20 | const getData = () =>
21 | new Promise((resolve) =>
22 | d3
23 | .dsv(',', '/data/client-list.csv', function results(d) {
24 | return d
25 | })
26 | .then(function results(data) {
27 | resolve((data as unknown) as clientsObject[])
28 | })
29 | )
30 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/widgets/ClientsWidget/ClientsWidget.scss:
--------------------------------------------------------------------------------
1 | .PreviousClients {
2 | }
3 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/widgets/ClientsWidget/ClientsWidget.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/ClientsWidget/ClientsWidget.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import ClientsWidget from './ClientsWidget'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow(
18 |
19 |
20 |
21 | )
22 | })
23 |
24 | test('It should mount', () => {
25 | expect(component.length).toBe(1)
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch07/world-map-widget/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch07/world-map-widget/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch07/world-map-widget/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch07/world-map-widget/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
2 | BROWSER=none
3 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*
2 | public/*
3 | docs/*
4 | templates/*
5 | src/react-app-env.d.ts
6 | src/serviceWorker.ts
7 | e2e/jest.config.js
8 | e2e/puppeteer_standalone.js
9 | jest-puppeteer.config.js
--------------------------------------------------------------------------------
/ch08/bubble-chart/.gitignore:
--------------------------------------------------------------------------------
1 | # misc
2 | .DS_Store
3 | package-lock.json
4 | yarn-error.log
5 | yarn.lock
6 | docs
7 |
8 | # IDEs
9 | .vscode
10 | .idea
11 |
12 | # dependencies
13 | /node_modules
14 | /.pnp
15 | .pnp.js
16 |
17 | # testing
18 | /coverage
19 | .nyc_output
20 |
21 | # production
22 | /build
23 |
24 | # misc
25 | .DS_Store
26 | .env.local
27 | .env.development.local
28 | .env.test.local
29 | .env.production.local
30 |
31 | npm-debug.log*
32 | yarn-debug.log*
33 | yarn-error.log*
34 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "printWidth": 200,
4 | "semi": false,
5 | "singleQuote": true,
6 | "tabWidth": 2
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch08/bubble-chart/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch08/bubble-chart/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch08/bubble-chart/public/favicon.ico
--------------------------------------------------------------------------------
/ch08/bubble-chart/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch08/bubble-chart/public/logo192.png
--------------------------------------------------------------------------------
/ch08/bubble-chart/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch08/bubble-chart/public/logo512.png
--------------------------------------------------------------------------------
/ch08/bubble-chart/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .appButtonFixed {
17 | position: fixed;
18 | left: -100px;
19 | top: 60px;
20 | }
21 |
22 | .App-header {
23 | background-color: #ffffff;
24 | min-height: 100vh;
25 | display: flex;
26 | flex-direction: column;
27 | align-items: center;
28 | justify-content: center;
29 | font-size: calc(10px + 2vmin);
30 | color: white;
31 | }
32 |
33 | .App-link {
34 | color: #61dafb;
35 | }
36 |
37 | @keyframes App-logo-spin {
38 | from {
39 | transform: rotate(0deg);
40 | }
41 | to {
42 | transform: rotate(360deg);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/components/BubbleChart/BubbleChart.scss:
--------------------------------------------------------------------------------
1 | .buttonFixed {
2 | position: fixed;
3 | top: 25px;
4 | left: 25px;
5 | }
6 |
7 | .bubbleText {
8 | text-shadow: 1px 0 0 darkslategrey, 0 1px 0 darkslategrey, -1px 0 0 darkslategrey, 0 -1px 0 darkslategrey;
9 | }
10 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/components/BubbleChart/BubbleChart.test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BubbleChart/BubbleChart.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import BubbleChart from './BubbleChart'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow(
18 |
19 |
20 |
21 | )
22 | })
23 |
24 | test('It should mount', () => {
25 | expect(component.length).toBe(1)
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/components/BubbleChart/types.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/BubbleChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | id: number
11 | name: string
12 | size: number
13 | fillColor: string
14 | }
15 |
16 | export type ForceData = {
17 | size: number
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/components/README:
--------------------------------------------------------------------------------
1 | Components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/hooks/README:
--------------------------------------------------------------------------------
1 | Hooks goes here. Check out some hooks examples here:
2 | https://github.com/EliEladElrom/react-tutorials
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch08/bubble-chart/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch08/bubble-chart/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch08/bubble-chart/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch08/bubble-chart/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch09/force-chart/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch09/force-chart/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch09/force-chart/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch09/force-chart/public/data/power_network.json:
--------------------------------------------------------------------------------
1 | {
2 | "results": [
3 | {
4 | "nodes": [
5 | {
6 | "name": "JavaScript / TypeScript",
7 | "radiusSize": 20,
8 | "fillColor": "#fa6502"
9 | }
10 | ],
11 | "links": [
12 | {
13 | "source": "Erase a character",
14 | "target": "JavaScript / TypeScript",
15 | "value": "How would you erase a character from a string?"
16 | }
17 | ]
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/ch09/force-chart/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch09/force-chart/public/favicon.ico
--------------------------------------------------------------------------------
/ch09/force-chart/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch09/force-chart/public/logo192.png
--------------------------------------------------------------------------------
/ch09/force-chart/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch09/force-chart/public/logo512.png
--------------------------------------------------------------------------------
/ch09/force-chart/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch09/force-chart/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #ffffff;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/App.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/App.tsx
6 | */
7 |
8 | import React from 'react'
9 | import './App.scss'
10 | import NetworksWidget from './widgets/NetworksWidget/NetworksWidget'
11 |
12 | function App() {
13 | return (
14 |
15 |
18 |
19 | )
20 | }
21 |
22 | export default App
23 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch09/force-chart/src/components/README:
--------------------------------------------------------------------------------
1 | Components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch09/force-chart/src/components/SimpleForceGraph/Circle.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/SimpleForceGraph/Circle.tsx
6 | */
7 |
8 | import * as React from 'react'
9 | import * as d3 from 'd3'
10 | import { Types } from './types'
11 |
12 | export default class Circle extends React.PureComponent<{ node: Types.node }> {
13 | ref: SVGCircleElement | undefined
14 |
15 | componentDidMount() {
16 | if (this.ref) d3.select(this.ref).data([this.props.node])
17 | }
18 |
19 | render() {
20 | return (
21 | // eslint-disable-next-line no-return-assign
22 | (this.ref = ref)}>
23 | {this.props.node.name}
24 |
25 | )
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/components/SimpleForceGraph/Labels.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/SimpleForceGraph/Labels.tsx
6 | */
7 |
8 | import * as React from 'react'
9 | import { Dispatch, SetStateAction } from 'react'
10 | import Label from './Label'
11 | import { Types } from './types'
12 |
13 | const uuid = require('react-uuid')
14 |
15 | export default class Labels extends React.PureComponent {
16 | render() {
17 | const labels = this.props.nodes.map((node: Types.node) => {
18 | return
19 | })
20 | return {labels}
21 | }
22 | }
23 |
24 | interface ILabelsProps {
25 | nodes: Types.node[]
26 | onNodeSelected: Dispatch>
27 | }
28 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/components/SimpleForceGraph/Links.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/SimpleForceGraph/Links.tsx
6 | */
7 |
8 | import * as React from 'react'
9 | import Link from './Link'
10 | import { Types } from './types'
11 |
12 | const uuid = require('react-uuid')
13 |
14 | export default class Links extends React.PureComponent<{ links: Types.link[] }> {
15 | render() {
16 | const links = this.props.links.map((link: Types.link) => {
17 | return
18 | })
19 | return {links}
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/components/SimpleForceGraph/SimpleForceGraph.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | background-color: #ffffff;
3 | }
4 |
5 | .node {
6 | stroke: #e0b7f6;
7 | stroke-width: 1px;
8 | }
9 |
10 | .link {
11 | stroke: #cfcccc;
12 | stroke-opacity: 1;
13 | stroke-width: 1px;
14 | }
15 |
16 | .label {
17 | font-size: 13px;
18 | fill: #999898;
19 | }
20 |
21 | .linkTextValue {
22 | display: block;
23 | font-size: 6px;
24 | fill: rgba(253, 165, 41, 1);
25 | }
26 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch09/force-chart/src/hooks/README:
--------------------------------------------------------------------------------
1 | Hooks goes here. Check out some hooks examples here:
2 | https://github.com/EliEladElrom/react-tutorials
--------------------------------------------------------------------------------
/ch09/force-chart/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch09/force-chart/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch09/force-chart/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch09/force-chart/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch09/force-chart/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/widgets/NetworksWidget/NetworksWidget.scss:
--------------------------------------------------------------------------------
1 | .wrapperDiv {
2 | width: 800px;
3 | height: 350px;
4 | clip-path: inset(10px 20px 30px 40px);
5 | }
6 |
7 | .selectedText {
8 | font-size: 13px;
9 | color: #373636;
10 | }
11 |
--------------------------------------------------------------------------------
/ch09/force-chart/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch09/force-chart/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch09/force-chart/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch09/force-chart/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch09/force-chart/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch09/force-chart/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch09/force-chart/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch09/force-chart/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/data/bar.csv:
--------------------------------------------------------------------------------
1 | framework,carat
2 | jQuery,43.3
3 | React.js,35.9
4 | Angular,25.1
5 | ASP.NET,21.9
6 | Express,21.2
7 | .NET Core,19.1
8 | Vue.js,17.3
9 | Spring,16.4
10 | Angular.js,16.1
11 | Django,14.2
12 | Flask,14.2
13 | Laravel,11.1
14 | Rails,7.0
15 | Symfony,14.4
16 | Gatsby, 4.0
17 | Drupal, 3.2
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/data/pie.csv:
--------------------------------------------------------------------------------
1 | name,value
2 | a,25
3 | b,3
4 | c,45
5 | d,7
6 | e,20
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch10/react-chart-libraries/build/favicon.ico
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch10/react-chart-libraries/build/logo192.png
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch10/react-chart-libraries/build/logo512.png
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/build/static/css/main.7a4fb01d.chunk.css:
--------------------------------------------------------------------------------
1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.App{text-align:center}.App-logo{height:40vmin;pointer-events:none}@media (prefers-reduced-motion:no-preference){.App-logo{animation:App-logo-spin 20s linear infinite}}.App-header{background-color:#fff;min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:calc(5px + 2vmin);color:#fff}.App-link{color:#61dafb}@keyframes App-logo-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}
2 | /*# sourceMappingURL=main.7a4fb01d.chunk.css.map */
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/data/bar.csv:
--------------------------------------------------------------------------------
1 | framework,carat
2 | jQuery,43.3
3 | React.js,35.9
4 | Angular,25.1
5 | ASP.NET,21.9
6 | Express,21.2
7 | .NET Core,19.1
8 | Vue.js,17.3
9 | Spring,16.4
10 | Angular.js,16.1
11 | Django,14.2
12 | Flask,14.2
13 | Laravel,11.1
14 | Rails,7.0
15 | Symfony,14.4
16 | Gatsby, 4.0
17 | Drupal, 3.2
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/data/pie.csv:
--------------------------------------------------------------------------------
1 | name,value
2 | a,25
3 | b,3
4 | c,45
5 | d,7
6 | e,20
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch10/react-chart-libraries/public/favicon.ico
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch10/react-chart-libraries/public/logo192.png
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch10/react-chart-libraries/public/logo512.png
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: white;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(5px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/components/README:
--------------------------------------------------------------------------------
1 | Components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/components/SimpleLineChart/types.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/SimpleLineChart/types.ts
6 | */
7 |
8 | export namespace Types {
9 | export type Data = {
10 | date: string
11 | value: number
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/components/SimplePie/SimplePie.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/SimplePie/SimplePie.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { VictoryPie } from 'victory'
10 |
11 | const SimplePie = () => {
12 | return (
13 |
14 |
21 |
22 | )
23 | }
24 |
25 | export default SimplePie
26 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/hooks/README:
--------------------------------------------------------------------------------
1 | Hooks goes here. Check out some hooks examples here:
2 | https://github.com/EliEladElrom/react-tutorials
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/recoil/selectors/calendarDataSelectors.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/recoil/selectors/calendarDataSelectors.ts
6 | */
7 |
8 | import { selector } from 'recoil'
9 |
10 | export const getCalendarData = selector({
11 | key: 'getCalendarData',
12 | get: () => {
13 | return getData()
14 | },
15 | })
16 | const getData = () =>
17 | new Promise((resolve) =>
18 | fetch(`${process.env.PUBLIC_URL}/data/calendar.json`).then((response) => {
19 | if (response.status !== 200) {
20 | // eslint-disable-next-line no-console
21 | console.log(`Houston, we have a problem! ${response.status}`)
22 | return
23 | }
24 | response.json().then((data) => {
25 | resolve(data)
26 | })
27 | })
28 | )
29 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/recoil/selectors/lineDataSelectors.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | File: src/recoil/selectors/lineDataSelectors.ts
6 | */
7 |
8 | import { selector } from 'recoil'
9 | import * as d3 from 'd3'
10 |
11 | export const getLineData = selector({
12 | key: 'getLineData',
13 | get: () => {
14 | return getData()
15 | },
16 | })
17 | const getData = () =>
18 | new Promise((resolve) =>
19 | d3
20 | .dsv(',', '/Data/line.csv', (d) => {
21 | const res = d as { date: string; data: string }
22 | const value = parseFloat(res.data as string)
23 | const { date } = res
24 | return {
25 | date,
26 | value,
27 | }
28 | })
29 | .then((data) => {
30 | resolve(data)
31 | })
32 | )
33 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch10/react-chart-libraries/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch11/knick-knacks/build/favicon.ico
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch11/knick-knacks/build/logo192.png
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch11/knick-knacks/build/logo512.png
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/static/css/main.5c815069.chunk.css:
--------------------------------------------------------------------------------
1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.App{text-align:center}.App-logo{height:40vmin;pointer-events:none}@media (prefers-reduced-motion:no-preference){.App-logo{animation:App-logo-spin 20s linear infinite}}.App-header{background-color:#282c34;min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@keyframes App-logo-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}
2 | /*# sourceMappingURL=main.5c815069.chunk.css.map */
--------------------------------------------------------------------------------
/ch11/knick-knacks/build/static/js/3.ff43eb1d.chunk.js:
--------------------------------------------------------------------------------
1 | (this["webpackJsonpknick-knacks"]=this["webpackJsonpknick-knacks"]||[]).push([[3],{73:function(t,e,a){"use strict";a.r(e);var n=a(0),r=a.n(n),c=a(71);e.default=function(){var t=r.a.createRef();Object(n.useEffect)((function(){e()}));var e=function(){Object(c.a)(t.current).append("p").text("Hello World"),Object(c.a)("svg").append("g").attr("transform","translate(250, 0)").append("rect").attr("width",500).attr("height",500).attr("fill","tomato")};return r.a.createElement("div",{className:"Rectangle",ref:t},r.a.createElement("svg",{width:"500",height:"500"},r.a.createElement("g",{transform:"translate(0, 0)"},r.a.createElement("rect",{width:"500",height:"500",fill:"green"}))))}}}]);
2 | //# sourceMappingURL=3.ff43eb1d.chunk.js.map
--------------------------------------------------------------------------------
/ch11/knick-knacks/e2e/global.d.ts:
--------------------------------------------------------------------------------
1 | // globals defined in jest.config.js need to be included in this `d.ts`
2 | // file to avoid TS lint errors
3 | declare let SERVER_URL: string
4 | declare let JEST_TIMEOUT: number
--------------------------------------------------------------------------------
/ch11/knick-knacks/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'jest-puppeteer',
3 | globals: {
4 | SERVER_URL: 'http://localhost:3000',
5 | JEST_TIMEOUT: 50000
6 | },
7 | testRegex: './*\\.test\\.tsx$'
8 | }
9 | console.log('RUNNING E2E INTEGRATION TESTS - MAKE SURE PORT 3000 IS NOT IN USAGE')
--------------------------------------------------------------------------------
/ch11/knick-knacks/jest-puppeteer.config.js:
--------------------------------------------------------------------------------
1 | // jest-puppeteer.config.js
2 | module.exports = {
3 | server: {
4 | command: `yarn start`,
5 | port: 3000,
6 | launchTimeout: 20000,
7 | debug: true,
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch11/knick-knacks/public/favicon.ico
--------------------------------------------------------------------------------
/ch11/knick-knacks/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch11/knick-knacks/public/logo192.png
--------------------------------------------------------------------------------
/ch11/knick-knacks/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/integrating-d3.js-with-react/f4cdad62693a1d576e9f6371be7fb4640d71e264/ch11/knick-knacks/public/logo512.png
--------------------------------------------------------------------------------
/ch11/knick-knacks/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | // src/App.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import App from './App'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1)
14 | })
15 | })
16 |
17 | /*
18 | Update this file once it's changed. For instance to check if a component you added
19 | include in App.tsx;
20 |
21 | import { shallow } from "enzyme";
22 | import Calculator from "./components/SomeComponent/SomeComponent";
23 |
24 | test('should render SomeComponent', () => {
25 | const wrapper = shallow();
26 | const calculator = wrapper.find(SomeComponent);
27 | expect(calculator.exists()).toBe(true);
28 | })
29 | */
30 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/AppRouter.test.tsx:
--------------------------------------------------------------------------------
1 | // src/AppRouter.test.tsx
2 | import React from 'react'
3 | import { shallow } from 'enzyme'
4 | import AppRouter from './AppRouter'
5 |
6 | describe('', () => {
7 | let component
8 |
9 | beforeEach(() => {
10 | component = shallow()
11 | })
12 |
13 | test('renders without crashing', () => {
14 | expect(component.length).toBe(1)
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/assets/README:
--------------------------------------------------------------------------------
1 | Break down your assets by names: about, home, etc.
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/components/README:
--------------------------------------------------------------------------------
1 | Components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component UserButton
3 | $ npx generate-react-cli component Rectangle --type=d3class
4 | $ npx generate-react-cli component Rectangle --type=d3
5 | $ npx generate-react-cli component Login --type=recoil
6 | $ npx generate-react-cli component MyButton --type=materialui
7 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/features/README:
--------------------------------------------------------------------------------
1 | features components goes here.
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/hooks/README:
--------------------------------------------------------------------------------
1 | Hooks goes here. Check out some hooks examples here:
2 | https://github.com/EliEladElrom/react-tutorials
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
4 | -webkit-font-smoothing: antialiased;
5 | -moz-osx-font-smoothing: grayscale;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/layout/README:
--------------------------------------------------------------------------------
1 | layout components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component BoxLayout --type=layout
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/model/README:
--------------------------------------------------------------------------------
1 | Place all your object model files here, for example: userObject.ts
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/model/userObject.ts
8 | */
9 |
10 | export interface userObject {
11 | email: string
12 | password: string
13 | }
14 |
15 | export const initUser = (): userObject => ({
16 | email: '',
17 | password: '',
18 | })
19 |
20 | Next, create an index and add model object for easy access, example: index.ts
21 |
22 | /*
23 | Author: Eli Elad Elrom
24 | Website: https://EliElrom.com
25 | License: MIT License
26 | File: src/model/index.ts
27 | */
28 |
29 | export * from './userObject'
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/pages/README:
--------------------------------------------------------------------------------
1 | Pages components goes here, you can generate with generate-react-cli, example;
2 | $ npx generate-react-cli component HomePage --type=page
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/recoil/atoms/README:
--------------------------------------------------------------------------------
1 | Recoil atoms goes here, example: userAtoms.ts;
2 |
3 | /*
4 | Author: Eli Elad Elrom
5 | Website: https://EliElrom.com
6 | License: MIT License
7 | File: src/recoil/atoms/userAtoms.ts
8 | */
9 |
10 | import { atom } from 'recoil'
11 | import { initUser } from '../../model'
12 |
13 | export const userState = atom({
14 | key: 'UserState',
15 | default: initUser(),
16 | })
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // src/redux/store.ts
2 |
3 | import { configureStore, combineReducers } from '@reduxjs/toolkit'
4 |
5 | const store = configureStore({
6 | reducer: combineReducers({
7 | // your reducers goes here
8 | }),
9 | })
10 |
11 | export default store
12 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect'
6 |
7 | import { configure } from 'enzyme'
8 | import Adapter from 'enzyme-adapter-react-16'
9 |
10 | configure({ adapter: new Adapter() })
11 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/src/widgets/README:
--------------------------------------------------------------------------------
1 | components goes here, you can generate with generate-react-cli, examples;
2 | $ npx generate-react-cli component MyWidget --type=widget
--------------------------------------------------------------------------------
/ch11/knick-knacks/templates/component/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch11/knick-knacks/templates/component/test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 | import TemplateName from './TemplateName';
4 |
5 | describe('', () => {
6 | let component;
7 |
8 | beforeEach(() => {
9 | component = shallow();
10 | });
11 |
12 | test('It should mount', () => {
13 | expect(component.length).toBe(1);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/templates/component/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import TemplateName from './TemplateName'
11 |
12 | describe('', () => {
13 | let component
14 |
15 | beforeEach(() => {
16 | component = shallow()
17 | });
18 |
19 | test('It should mount', () => {
20 | expect(component.length).toBe(1)
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/templates/page/style.scss:
--------------------------------------------------------------------------------
1 | .TemplateName {
2 | }
--------------------------------------------------------------------------------
/ch11/knick-knacks/templates/recoil/component.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.tsx
6 | */
7 |
8 | import React, { useEffect } from 'react'
9 | import './TemplateName.scss'
10 | // import { useRecoilValue } from 'recoil'
11 |
12 | const TemplateName = () /* or ( props : ITemplateNameProps ) */ => {
13 | const results: boolean = true // useRecoilValue( getMethod )
14 | useEffect(() => {
15 | // TODO
16 | })
17 | return (
18 | <>
19 | {results ? (
20 |
21 | TemplateName Loaded
22 |
23 | ) : (
24 | <>Loading>
25 | )}
26 | >
27 | )
28 | }
29 |
30 | /*
31 | interface ITemplateNameProps {
32 | // TODO
33 | }
34 | */
35 |
36 | export default TemplateName
37 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/templates/recoil/test.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: src/component/TemplateName/TemplateName.test.tsx
6 | */
7 |
8 | import React from 'react'
9 | import { shallow } from 'enzyme'
10 | import { RecoilRoot } from 'recoil'
11 | import TemplateName from './TemplateName'
12 |
13 | describe('', () => {
14 | let component
15 |
16 | beforeEach(() => {
17 | component = shallow()
18 | })
19 |
20 | test('It should mount', () => {
21 | expect(component.length).toBe(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/ch11/knick-knacks/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "es6", "dom",
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitThis": true,
13 | "strictNullChecks": true,
14 | "allowJs": true,
15 | "skipLibCheck": true,
16 | "esModuleInterop": true,
17 | "allowSyntheticDefaultImports": true,
18 | "strict": true,
19 | "forceConsistentCasingInFileNames": true,
20 | "module": "esnext",
21 | "moduleResolution": "node",
22 | "resolveJsonModule": true,
23 | "isolatedModules": true,
24 | "noEmit": true,
25 | "jsx": "react"
26 | },
27 | "include": [
28 | "src",
29 | "e2e"
30 | ],
31 | "exclude": [
32 | "**/templates/*",
33 | "**/node_modules/*"
34 | ]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/ch12/nextjs-ts-chart/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/ch12/nextjs-ts-chart/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/ch12/nextjs-ts-chart/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs-ts-chart",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start -p $PORT"
9 | },
10 | "dependencies": {
11 | "@types/d3-selection": "^2.0.0",
12 | "d3-selection": "^2.0.0",
13 | "next": "10.0.7",
14 | "react": "17.0.1",
15 | "react-dom": "17.0.1"
16 | },
17 | "devDependencies": {
18 | "@types/node": "^14.14.30",
19 | "@types/react": "^17.0.2",
20 | "express": "^4.17.1",
21 | "typescript": "^4.1.5"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch12/nextjs-ts-chart/server.js:
--------------------------------------------------------------------------------
1 | /*
2 | Author: Eli Elad Elrom
3 | Website: https://EliElrom.com
4 | License: MIT License
5 | Component: server.js
6 | */
7 |
8 | const express = require('express')
9 | const next = require('next')
10 |
11 | const port = process.env.PORT || 9000;
12 | const dev = process.env.NODE_ENV !== 'production'
13 | const app = next({ dev })
14 | const handle = app.getRequestHandler()
15 |
16 | app.prepare()
17 | .then(() => {
18 | const server = express()
19 |
20 | server.get('*', (req, res) => {
21 | return handle(req, res)
22 | })
23 |
24 | server.listen(port, (err) => {
25 | if (err) throw err
26 | console.log(`Server Ready on http://localhost:${port}`)
27 | })
28 | })
29 | .catch((ex) => {
30 | console.error(ex.stack)
31 | process.exit(1)
32 | })
--------------------------------------------------------------------------------
/ch12/nextjs-ts-chart/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "preserve"
20 | },
21 | "include": [
22 | "next-env.d.ts",
23 | "**/*.ts",
24 | "**/*.tsx"
25 | ],
26 | "exclude": [
27 | "node_modules"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/errata.md:
--------------------------------------------------------------------------------
1 | # Errata for *Integrating D3.js with React*
2 |
3 | On **page xx** [Summary of error]:
4 |
5 | Details of error here. Highlight key pieces in **bold**.
6 |
7 | ***
8 |
9 | On **page xx** [Summary of error]:
10 |
11 | Details of error here. Highlight key pieces in **bold**.
12 |
13 | ***
--------------------------------------------------------------------------------