diff --git a/docusaurus.config.js b/docusaurus.config.js index d74d0b11..d3f57deb 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -38,8 +38,11 @@ const config = { theme: { // It looks like Docosaurus doesn't yet support directly importing // this style in the EmailSignupForm component, so as a workaround - // it is imported here. - customCss: [require.resolve( 'react-mailchimp-email-signup-form/dist/esm/index.css')], + // it is imported here, along with other stylesheets we need. + customCss: [ + require.resolve('react-mailchimp-email-signup-form/dist/esm/index.css'), + require.resolve('asciinema-player/dist/bundle/asciinema-player.css'), + ], }, gtag: { trackingID: 'G-8HZFMZV9Z4', diff --git a/makefile b/makefile index ce504485..8879f8d4 100644 --- a/makefile +++ b/makefile @@ -16,6 +16,7 @@ serve: # folder as if we don't have them we should definitely not deploy. .PHONY: build build: + npx tsc # test for typescript types... mkdir -p ./static/downloads ./scripts/build-samples.sh cp ./artifacts/samples.zip ./static/downloads/effective-shell-samples.zip diff --git a/package-lock.json b/package-lock.json index 862a4342..c946c59c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1570,6 +1570,19 @@ "webpack": "^5.61.0" } }, + "@docusaurus/module-type-aliases": { + "version": "2.0.0-beta.18", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-beta.18.tgz", + "integrity": "sha512-e6mples8FZRyT7QyqidGS6BgkROjM+gljJsdOqoctbtBp+SZ5YDjwRHOmoY7eqEfsQNOaFZvT2hK38ui87hCRA==", + "dev": true, + "requires": { + "@docusaurus/types": "2.0.0-beta.18", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*" + } + }, "@docusaurus/plugin-content-blog": { "version": "2.0.0-beta.15", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-beta.15.tgz", @@ -1800,6 +1813,75 @@ "tslib": "^2.3.1" } }, + "@docusaurus/types": { + "version": "2.0.0-beta.18", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.0.0-beta.18.tgz", + "integrity": "sha512-zkuSmPQYP3+z4IjGHlW0nGzSSpY7Sit0Nciu/66zSb5m07TK72t6T1MlpCAn/XijcB9Cq6nenC3kJh66nGsKYg==", + "dev": true, + "requires": { + "commander": "^5.1.0", + "joi": "^17.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.70.0", + "webpack-merge": "^5.8.0" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", + "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "webpack": { + "version": "5.71.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.71.0.tgz", + "integrity": "sha512-g4dFT7CFG8LY0iU5G8nBL6VlkT21Z7dcYDpJAEJV5Q1WLb9UwnFbrem1k7K52ILqEmomN7pnzWFxxE6SlDY56A==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.9.2", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.3" + } + } + } + }, "@docusaurus/utils": { "version": "2.0.0-beta.15", "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.0.0-beta.15.tgz", @@ -2148,6 +2230,12 @@ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" }, + "@tsconfig/docusaurus": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@tsconfig/docusaurus/-/docusaurus-1.0.5.tgz", + "integrity": "sha512-KM/TuJa9fugo67dTGx+ktIqf3fVc077J6jwHu845Hex4EQf7LABlNonP/mohDKT0cmncdtlYVHHF74xR/YpThg==", + "dev": true + }, "@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -2234,6 +2322,12 @@ "@types/unist": "*" } }, + "@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "dev": true + }, "@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", @@ -2305,6 +2399,38 @@ "csstype": "^3.0.2" } }, + "@types/react-router": { + "version": "5.1.18", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz", + "integrity": "sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g==", + "dev": true, + "requires": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "@types/react-router-config": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.6.tgz", + "integrity": "sha512-db1mx37a1EJDf1XeX8jJN7R3PZABmJQXR8r28yUjVMFSjkmnQo6X6pOEEmNl+Tp2gYQOGPdYbFIipBtdElZ3Yg==", + "dev": true, + "requires": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dev": true, + "requires": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, "@types/retry": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", @@ -2684,6 +2810,16 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, + "asciinema-player": { + "version": "3.0.0-rc.1", + "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.0.0-rc.1.tgz", + "integrity": "sha512-r0yRCnifQ+UuyInLBwanupOUk7FPIs1NgD3D+egaSCXzK1+PSQf0aHo/dfpZFY2sml9mA0cqUHJFQ4KnuUJS1Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.15.4", + "solid-js": "^1.1.6" + } + }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", @@ -5231,6 +5367,15 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7094,6 +7239,19 @@ "react-side-effect": "^2.1.0" } }, + "react-helmet-async": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.2.3.tgz", + "integrity": "sha512-mCk2silF53Tq/YaYdkl2sB+/tDoPnaxN7dFS/6ZLJb/rhUY2EWGI5Xj2b4jHppScMqY45MbgPSwTxDchKpZ5Kw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -7944,6 +8102,12 @@ "kind-of": "^6.0.2" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "dev": true + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8018,6 +8182,12 @@ "websocket-driver": "^0.7.4" } }, + "solid-js": { + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.3.13.tgz", + "integrity": "sha512-1EBEIW9u2yqT5QNjFdvz/tMAoKsDdaRA2Jbgykd2Dt13Ia0D4mV+BFvPkOaseSyu7DsMKS23+ZZofV8BVKmpuQ==", + "dev": true + }, "sort-css-media-queries": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.0.4.tgz", @@ -8374,6 +8544,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true + }, "ua-parser-js": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", diff --git a/package.json b/package.json index e2abb6a8..17b113b2 100644 --- a/package.json +++ b/package.json @@ -35,5 +35,11 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "^2.0.0-beta.18", + "@tsconfig/docusaurus": "^1.0.5", + "asciinema-player": "^3.0.0-rc.1", + "typescript": "^4.6.3" } } diff --git a/src/components/AsciinemaPlayer/AsciinemaPlayer.tsx b/src/components/AsciinemaPlayer/AsciinemaPlayer.tsx new file mode 100644 index 00000000..7693d2d9 --- /dev/null +++ b/src/components/AsciinemaPlayer/AsciinemaPlayer.tsx @@ -0,0 +1,43 @@ +// @ts-check +// This react component is based on the excellent code at: +// https://github.com/asciinema/asciinema-player/issues/72 +// Props to https://github.com/dunnkers + +import React, { useEffect, useRef } from 'react'; +import * as AsciinemaPlayerLibrary from 'asciinema-player'; + +type AsciinemaPlayerProps = { + src: string; + style: React.CSSProperties; + // START asciinemaOptions + cols: string; + rows: string; + autoPlay: boolean + preload: boolean; + loop: boolean | number; + startAt: number | string; + speed: number; + idleTimeLimit: number; + theme: string; + poster: string; + fit: string; + fontSize: string; + // END asciinemaOptions +}; + +const AsciinemaPlayer: React.FC = ({ + src, + style, + ...asciinemaOptions +}) => { + const ref = useRef(null); + + useEffect(() => { + const currentRef = ref.current; + AsciinemaPlayerLibrary.create(src, currentRef, asciinemaOptions); + }, [src]); + + return
; +}; + +export default AsciinemaPlayer; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..4ffb6f0f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@tsconfig/docusaurus/tsconfig.json" +}