diff --git a/docs/index.css b/docs/index.css index 03ee68be7..ee6209ea3 100644 --- a/docs/index.css +++ b/docs/index.css @@ -24,15 +24,23 @@ .content h1 { @apply text-2xl font-bold; + padding-top: 48px; + margin-top: -48px; } .content h2 { @apply text-xl font-bold; + padding-top: 48px; + margin-top: -48px; } .content h3 { @apply text-lg font-bold; + padding-top: 48px; + margin-top: -48px; } .content h4 { @apply text-base font-bold; + padding-top: 48px; + margin-top: -48px; } .content a { @@ -47,3 +55,7 @@ padding-inline-start: 30px; @apply list-disc; } + +.outline a { + @apply text-gray-600 hover:text-yellow-400 mb-1 inline-block transition-colors; +} diff --git a/docs/markdown/basics/reactivity.md b/docs/markdown/basics/reactivity.md index dd6bb8232..d2f221152 100644 --- a/docs/markdown/basics/reactivity.md +++ b/docs/markdown/basics/reactivity.md @@ -43,7 +43,7 @@ How does the `create_effect(...)` function know to execute the closure every tim Calling `create_effect` creates a new _"reactivity scope"_ and calling `state.get()` inside this scope adds itself as a _dependency_. Now, when `state.set(...)` is called, it automatically calls all its _dependents_, in this case, `state` as it was called inside the closure. -> #### What's that `cloned!` macro doing? +> ## What's that `cloned!` macro doing? > > The `cloned!` macro is an utility macro for cloning the variables into the following expression. The previous `create_effect` function call could very well have been written as: > @@ -74,7 +74,7 @@ assert_eq!(*double.get(), 2); Now that you understand `sycamore`'s reactivity system, we can look at how to use this to update the DOM. -### Using reactivity with DOM updates +## Using reactivity with DOM updates Reactivity is automatically built-in into the `template!` macro. Say we have the following code: diff --git a/docs/package-lock.json b/docs/package-lock.json index a7d778dee..610d3a3f3 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -11,8 +11,6 @@ "autoprefixer": "^10.2.6", "concurrently": "^6.2.0", "cross-env": "^7.0.3", - "postcss": "^8.3.1", - "postcss-cli": "^8.3.1", "tailwindcss": "^2.1.4" } }, @@ -247,24 +245,6 @@ "integrity": "sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==", "dev": true }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/autoprefixer": { "version": "10.2.6", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.6.tgz", @@ -631,15 +611,6 @@ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, - "node_modules/dependency-graph": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz", - "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -663,18 +634,6 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -770,21 +729,6 @@ "url": "https://www.patreon.com/infusion" } }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -820,18 +764,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -864,26 +796,6 @@ "node": ">= 6" } }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", @@ -926,15 +838,6 @@ "node": ">=8" } }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/import-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz", @@ -1120,36 +1023,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "node_modules/lodash.forown": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", - "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "node_modules/lodash.groupby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", - "integrity": "sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=", - "dev": true - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, "node_modules/lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", @@ -1364,15 +1237,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/postcss": { "version": "8.3.5", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz", @@ -1391,35 +1255,6 @@ "url": "https://opencollective.com/postcss/" } }, - "node_modules/postcss-cli": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", - "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "chokidar": "^3.3.0", - "dependency-graph": "^0.9.0", - "fs-extra": "^9.0.0", - "get-stdin": "^8.0.0", - "globby": "^11.0.0", - "postcss-load-config": "^3.0.0", - "postcss-reporter": "^7.0.0", - "pretty-hrtime": "^1.0.3", - "read-cache": "^1.0.0", - "slash": "^3.0.0", - "yargs": "^16.0.0" - }, - "bin": { - "postcss": "bin/postcss" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, "node_modules/postcss-js": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-3.0.3.tgz", @@ -1482,30 +1317,6 @@ "postcss": "^8.1.13" } }, - "node_modules/postcss-reporter": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.2.tgz", - "integrity": "sha512-JyQ96NTQQsso42y6L1H1RqHfWH1C3Jr0pt91mVv5IdYddZAE9DUZxuferNgk6q0o6vBVOrfVJb10X1FgDzjmDw==", - "dev": true, - "dependencies": { - "colorette": "^1.2.1", - "lodash.difference": "^4.5.0", - "lodash.forown": "^4.4.0", - "lodash.get": "^4.4.2", - "lodash.groupby": "^4.6.0", - "lodash.sortby": "^4.7.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/postcss-selector-parser": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", @@ -1581,15 +1392,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", - "dev": true, - "dependencies": { - "pify": "^2.3.0" - } - }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -1769,15 +1571,6 @@ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "dev": true }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map-js": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", @@ -2288,18 +2081,6 @@ "integrity": "sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==", "dev": true }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, "autoprefixer": { "version": "10.2.6", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.6.tgz", @@ -2574,12 +2355,6 @@ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, - "dependency-graph": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz", - "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", - "dev": true - }, "detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -2597,15 +2372,6 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, "dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -2682,18 +2448,6 @@ "integrity": "sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==", "dev": true }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2719,12 +2473,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -2748,20 +2496,6 @@ "is-glob": "^4.0.1" } }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", @@ -2795,12 +2529,6 @@ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, "import-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz", @@ -2950,36 +2678,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.forown": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", - "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lodash.groupby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", - "integrity": "sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=", - "dev": true - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", @@ -3140,12 +2838,6 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, "postcss": { "version": "8.3.5", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz", @@ -3157,26 +2849,6 @@ "source-map-js": "^0.6.2" } }, - "postcss-cli": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", - "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "chokidar": "^3.3.0", - "dependency-graph": "^0.9.0", - "fs-extra": "^9.0.0", - "get-stdin": "^8.0.0", - "globby": "^11.0.0", - "postcss-load-config": "^3.0.0", - "postcss-reporter": "^7.0.0", - "pretty-hrtime": "^1.0.3", - "read-cache": "^1.0.0", - "slash": "^3.0.0", - "yargs": "^16.0.0" - } - }, "postcss-js": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-3.0.3.tgz", @@ -3207,20 +2879,6 @@ "postcss-selector-parser": "^6.0.4" } }, - "postcss-reporter": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.2.tgz", - "integrity": "sha512-JyQ96NTQQsso42y6L1H1RqHfWH1C3Jr0pt91mVv5IdYddZAE9DUZxuferNgk6q0o6vBVOrfVJb10X1FgDzjmDw==", - "dev": true, - "requires": { - "colorette": "^1.2.1", - "lodash.difference": "^4.5.0", - "lodash.forown": "^4.4.0", - "lodash.get": "^4.4.2", - "lodash.groupby": "^4.6.0", - "lodash.sortby": "^4.7.0" - } - }, "postcss-selector-parser": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", @@ -3267,15 +2925,6 @@ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", - "dev": true, - "requires": { - "pify": "^2.3.0" - } - }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -3408,12 +3057,6 @@ } } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "source-map-js": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", diff --git a/docs/package.json b/docs/package.json index 0cfd6b463..fc38156dd 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,8 +10,6 @@ "autoprefixer": "^10.2.6", "concurrently": "^6.2.0", "cross-env": "^7.0.3", - "postcss": "^8.3.1", - "postcss-cli": "^8.3.1", "tailwindcss": "^2.1.4" }, "private": true diff --git a/docs/src/content.rs b/docs/src/content.rs index 17e60540f..41ec1c259 100644 --- a/docs/src/content.rs +++ b/docs/src/content.rs @@ -1,4 +1,4 @@ -use pulldown_cmark::{html, Options, Parser}; +use pulldown_cmark::{html, CowStr, Event, Options, Parser, Tag}; use sycamore::prelude::*; use wasm_bindgen::prelude::*; use web_sys::HtmlElement; @@ -11,6 +11,51 @@ extern "C" { async fn fetch_md(url: &str) -> JsValue; } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Outline { + name: String, + children: Vec, +} + +#[component(OutlineView)] +pub fn outline_view(outline: StateHandle>) -> Template { + template! { + ul(class="mt-4 text-sm pl-2 border-l border-gray-400") { + Indexed(IndexedProps { + iterable: outline, + template: |item| { + let Outline { name, children } = item; + let nested = children.iter().map(|x| { + let name = x.name.clone(); + let href = format!("#{}", x.name.trim().to_lowercase().replace(" ", "-")); + template! { + li { + a(href=href) { + (name) + } + } + } + }).collect(); + let nested = Template::new_fragment(nested); + + let href = format!("#{}", name.trim().to_lowercase().replace(" ", "-")); + + template! { + li { + a(href=href) { + (name) + } + ul(class="ml-3") { + (nested) + } + } + } + } + }) + } + } +} + #[component(Content)] pub fn content(pathname: String) -> Template { let location = web_sys::window() @@ -23,21 +68,71 @@ pub fn content(pathname: String) -> Template { let docs_container_ref = NodeRef::::new(); let markdown = Signal::new(String::new()); - let html = create_memo(cloned!((markdown) => move || { + let outline = Signal::new(Vec::new()); + let html = create_memo(cloned!((markdown, outline) => move || { let markdown = markdown.get(); + let mut outline_tmp = Vec::new(); + let mut tmp = None; + let options = Options::all(); - let parser = Parser::new_ext(markdown.as_ref(), options); + let parser = Parser::new_ext(markdown.as_ref(), options) + .filter_map(|event| { + match event { + Event::Start(Tag::Heading(level)) => { + if level == 1 { + Some(event) + } else { + tmp = Some(Outline{ + name: String::new(), + children: Vec::new(), + }); + None + } + }, + Event::End(Tag::Heading(level)) => { + if level == 1 { + Some(event) + } else { + let tmp = tmp.take().unwrap(); + let anchor = tmp.name.trim().to_lowercase().replace(" ", "-"); + let name = tmp.name.clone(); + if level == 2 { + outline_tmp.push(tmp); + } else { + let l = outline_tmp.last_mut().expect("cannot have non level 2 heading at root"); + l.children.push(tmp); + } + Some(Event::Html(CowStr::from(format!("{}", level, anchor, name, level)))) + } + }, + Event::Text(ref text) | Event::Code(ref text) => { + if tmp.is_some() { + tmp.as_mut().unwrap().name += text; + // Some(event) + None + } else { + Some(event) + } + } + _ => Some(event), + } + }); + + let mut html = String::new(); + html::push_html(&mut html, parser); - let mut output = String::new(); - html::push_html(&mut output, parser); + outline.set(outline_tmp); - output + html })); - create_effect(cloned!((docs_container_ref) => move || { + create_effect(cloned!((html, docs_container_ref) => move || { if !html.get().is_empty() { - docs_container_ref.get::().unchecked_into::().set_inner_html(html.get().as_ref()); + docs_container_ref + .get::() + .unchecked_into::() + .set_inner_html(html.get().as_ref()); highlight_all(); } })); @@ -55,9 +150,12 @@ pub fn content(pathname: String) -> Template { div(class="flex-none") { crate::sidebar::Sidebar() } - div(ref=docs_container_ref, class="content flex-1 min-w-0 pr-4 mb-2") { + div(ref=docs_container_ref, class="content flex-1 min-w-0 pr-4 mb-2 lg:mr-44") { "Loading..." } + div(class="outline flex-none hidden lg:block lg:w-44 fixed right-0") { + OutlineView(outline.handle()) + } } } } diff --git a/docs/src/header.rs b/docs/src/header.rs index 424847c8f..7f39925fc 100644 --- a/docs/src/header.rs +++ b/docs/src/header.rs @@ -9,30 +9,42 @@ fn nav() -> Template { div(class="flex flex-row justify-between items-center h-12") { // Brand section div(class="flex-initial") { - div(class="flex space-x-4 text-white") { - a(href="/#", class="py-2 px-3 text-sm font-medium \ + div(class="flex space-x-4") { + a(href="/#", class="py-2 px-3 text-sm text-white font-medium \ bg-gray-500 hover:bg-gray-600 transition-colors rounded") { "Sycamore" } + a( + href="https://crates.io/crates/sycamore", + class="text-gray-600 self-center", + target="_blank", + ) { + "v0.5.0-beta.1" + } } } // Links section - div(class="flex flex-row ml-2 space-x-4 text-white") { - a(class="py-2 px-3 text-sm text-gray-600 hover:text-gray-800 hover:underline transition", + div(class="flex flex-row ml-2 space-x-4 text-gray-600") { + a(class="py-2 px-3 text-sm hover:text-gray-800 hover:underline transition", href="/getting_started/installation", ) { "Book" } - a(class="py-2 px-3 text-sm text-gray-600 hover:text-gray-800 hover:underline transition", + a(class="py-2 px-3 text-sm hover:text-gray-800 hover:underline transition", href="https://docs.rs/sycamore", ) { "API" } - a(class="py-2 px-3 text-sm text-gray-600 hover:text-gray-800 hover:underline transition", + a(class="py-2 px-3 text-sm hover:text-gray-800 hover:underline transition", href="https://github.com/sycamore-rs/sycamore", ) { "Repository" } + a(class="py-2 px-3 text-sm hover:text-gray-800 hover:underline transition", + href="https://discord.gg/vDwFUmm6mU", + ) { + "Discord" + } } } } diff --git a/docs/src/index.rs b/docs/src/index.rs index 38f71557d..594f22b40 100644 --- a/docs/src/index.rs +++ b/docs/src/index.rs @@ -3,13 +3,13 @@ use sycamore::prelude::*; #[component(Index)] pub fn index() -> Template { template! { - div(class="flex flex-col items-center w-full") { + div(class="flex flex-col items-center w-full mb-10") { h1(class="text-5xl font-bold mt-20 mb-5") { "Sycamore" } p(class="mb-10") { - "Pure Rust + WASM web-apps" + "Fast isomorphic web apps in Rust + WASM" } a( href="/getting_started/installation", @@ -19,5 +19,35 @@ pub fn index() -> Template { "Read the Book" } } + div(class="text-white flex flex-col w-full md:flex-row space-y-4 md:space-y-0 md:space-x-4 mb-10") { + div(class="bg-red-500 md:flex-1 rounded-md p-6") { + h1(class="text-lg text-center font-semibold mb-3") { "Lightning speed" } + p { + "Sycamore harnesses the full power of " + a(href="https://www.rust-lang.org/", class="underline", target="_blank") { "Rust" } + " via " + a(href="https://webassembly.org/", class="underline", target="_blank") { "WebAssembly" } + ", giving you full \ + control over performance." + } + } + div(class="bg-amber-600 md:flex-1 rounded-md p-6") { + h1(class="text-lg text-center font-semibold mb-3") { "Ergonomic and intuitive" } + p { + "Write code that feels natural. Everything is built on " + a(href="/basics/reactivity", class="underline") { "reactive primitives" } + " without a cumbersome virtual DOM." + } + } + div(class="bg-yellow-600 md:flex-1 rounded-md p-6") { + h1(class="text-lg text-center font-semibold mb-3") { "No JavaScript" } + p(class="mb-2") { + "Had enough of JavaScript? So do we." + } + p { + "Create apps using Sycamore without touching a single line of JS." + } + } + } } } diff --git a/docs/src/main.rs b/docs/src/main.rs index dff87f093..55d2bb389 100644 --- a/docs/src/main.rs +++ b/docs/src/main.rs @@ -6,7 +6,7 @@ mod sidebar; use sycamore::prelude::*; use sycamore_router::{BrowserRouter, Route}; -#[derive(Route)] +#[derive(Debug, Route)] enum Routes { #[to("/")] Index, diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js index 57b35bdcc..cc3435bfb 100644 --- a/docs/tailwind.config.js +++ b/docs/tailwind.config.js @@ -1,3 +1,5 @@ +const colors = require('tailwindcss/colors') + module.exports = { jit: true, purge: [ @@ -6,6 +8,16 @@ module.exports = { darkMode: false, // or 'media' or 'class' theme: { extend: {}, + colors: { + transparent: 'transparent', + current: 'currentColor', + red: colors.red, + gray: colors.gray, + orange: colors.orange, + amber: colors.amber, + yellow: colors.yellow, + white: colors.white, + } }, variants: { extend: {}, diff --git a/packages/sycamore-router/src/router.rs b/packages/sycamore-router/src/router.rs index 790b0d00e..09d148b82 100644 --- a/packages/sycamore-router/src/router.rs +++ b/packages/sycamore-router/src/router.rs @@ -39,7 +39,7 @@ pub fn browser_router(render: impl Fn(R) -> Template + 'static) -> }); let pathname = PATHNAME.with(|p| p.borrow().clone().unwrap()); - // Listen to onpopstate. + // Listen to popstate event. let closure = Closure::wrap(Box::new(cloned!((pathname) => move || { pathname.set(web_sys::window().unwrap().location().pathname().unwrap()); })) as Box); @@ -49,7 +49,7 @@ pub fn browser_router(render: impl Fn(R) -> Template + 'static) -> .unwrap(); closure.forget(); - let path = create_memo(move || { + let path = create_selector(move || { pathname .get() .split('/') @@ -83,25 +83,32 @@ pub fn browser_router(render: impl Fn(R) -> Template + 'static) -> let a = a.unchecked_into::(); let origin = a.origin(); - let href = a.href(); let path = a.pathname(); - if origin == location.origin().unwrap() { - ev.prevent_default(); - if href != location.href().unwrap() { + let hash = a.hash(); + if Ok(origin) == location.origin() { + if Ok(&path) != location.pathname().as_ref() { + // Same origin, different path. + ev.prevent_default(); PATHNAME.with(|pathname| { let pathname = pathname.borrow().clone().unwrap(); pathname.set(path.to_string()); - + // Update History API. let history = web_sys::window().unwrap().history().unwrap(); history - .push_state_with_url( - &JsValue::UNDEFINED, - "", - Some(pathname.get().as_str()), - ) - .unwrap(); + .push_state_with_url( + &JsValue::UNDEFINED, + "", + Some(pathname.get().as_str()), + ) + .unwrap(); }); + } else if Ok(&hash) != location.hash().as_ref() { + // Same origin, same path, different anchor. + // Use default browser behavior. + } else { + // Same page. Do nothing. + ev.prevent_default(); } } }