From 3cd9299096ccac237e051778e2bd19166ed2129e Mon Sep 17 00:00:00 2001 From: "Angel D. Munoz" Date: Fri, 18 Jun 2021 19:52:20 -0500 Subject: [PATCH] Enable Fast --- build.ps1 | 24 +- src/Generator/Fast.fs | 13 +- src/Generator/package.json | 5 +- src/Generator/pnpm-lock.yaml | 4 +- src/website/package.json | 9 +- src/website/pnpm-lock.yaml | 199 +++++++++-------- src/website/snowpack.config.js | 5 +- src/website/src/App.fs | 156 ++++++++----- src/website/src/Main.fs | 44 +++- src/website/src/Pages/Home.fs | 52 ++++- src/website/src/Routes.fs | 8 + src/website/src/Theme.js | 11 + src/website/src/Types.fs | 4 + src/website/src/docs/fast/getting-started.md | 73 +++++++ src/website/src/docs/fast/themes.md | 217 +++++++++++++++++++ src/website/src/docs/getting-started.md | 133 ++++++++++++ src/website/src/docs/home-2.md | 3 + src/website/src/docs/home.md | 19 ++ src/website/src/styles.css | 3 + 19 files changed, 823 insertions(+), 159 deletions(-) create mode 100644 src/website/src/Theme.js create mode 100644 src/website/src/docs/fast/getting-started.md create mode 100644 src/website/src/docs/fast/themes.md create mode 100644 src/website/src/docs/getting-started.md create mode 100644 src/website/src/docs/home-2.md diff --git a/build.ps1 b/build.ps1 index 1e04365..205a16b 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,16 +1,30 @@ -Remove-Item Sutil.Shoelace -R -Force -ErrorAction Ignore; +[CmdletBinding()] +param ( + [Parameter(Mandatory = $true)] + [string] + $library = "shoelace" +) + +$project = $library -eq "shoelace" ? "Sutil.Shoelace" : "Sutil.Fast" + +$root = Get-Location + + +Remove-Item $library -R -Force -ErrorAction Ignore; Remove-Item dist -R -Force -ErrorAction Ignore; dotnet tool restore -dotnet run -C Release +set-location $root/src/Generator +dotnet run -C Release -- -cs $library if ($LASTEXITCODE -gt 0) { Exit 1 } -dotnet build src/Sutil.Shoelace/Sutil.Shoelace +dotnet build if ($LASTEXITCODE -gt 0) { Exit 1 } -dotnet fable --cwd src/Sutil.Shoelace/Sutil.Shoelace +Set-Location $root +dotnet fable --cwd src/$project if ($LASTEXITCODE -gt 0) { Exit 1 } -dotnet pack src/Sutil.Shoelace/Sutil.Shoelace -o dist \ No newline at end of file +dotnet pack src/$project -o dist \ No newline at end of file diff --git a/src/Generator/Fast.fs b/src/Generator/Fast.fs index c2240a0..2ba842e 100644 --- a/src/Generator/Fast.fs +++ b/src/Generator/Fast.fs @@ -1,5 +1,13 @@ namespace Sutil.Generator.Fast + +(* + DO NOT USE FANTOMAS OR ANOTHER FORMATTER + THAT CHANGES THE MULTI-LINE STRING STRUCTURE ON THIS FILE + IT WILL BREAK THE DOC COMMENTS GENERATION +*) + + open System open Sutil.Generator.Types open System.Web @@ -356,8 +364,8 @@ type Fast = fsharp;fable;svelte Angel D. Munoz - {version} - {version} + {version}-beta + {version}-beta netstandard2.0 true $(DefineConstants);FABLE_COMPILER; @@ -365,6 +373,7 @@ type Fast = + diff --git a/src/Generator/package.json b/src/Generator/package.json index 7b3ee90..4162b07 100644 --- a/src/Generator/package.json +++ b/src/Generator/package.json @@ -1,11 +1,10 @@ { "private": true, "dependencies": { - "@microsoft/fast-components": "^1.21.6", - "@shoelace-style/shoelace": "^2.0.0-beta.43" + "@microsoft/fast-components": "1.21.6", + "@shoelace-style/shoelace": "2.0.0-beta.43" }, "peerDependencies": { - "@microsoft/fast-foundation": "1.24.6", "lodash-es": "4.17.21" } } diff --git a/src/Generator/pnpm-lock.yaml b/src/Generator/pnpm-lock.yaml index 8414f6b..5f10a21 100644 --- a/src/Generator/pnpm-lock.yaml +++ b/src/Generator/pnpm-lock.yaml @@ -1,8 +1,8 @@ lockfileVersion: 5.3 specifiers: - '@microsoft/fast-components': ^1.21.6 - '@shoelace-style/shoelace': ^2.0.0-beta.43 + '@microsoft/fast-components': 1.21.6 + '@shoelace-style/shoelace': 2.0.0-beta.43 dependencies: '@microsoft/fast-components': 1.21.6 diff --git a/src/website/package.json b/src/website/package.json index 87fd69d..57a360a 100644 --- a/src/website/package.json +++ b/src/website/package.json @@ -14,11 +14,12 @@ "snowpack": "~3.5.1" }, "dependencies": { + "@microsoft/fast-components": "^1.21.6", + "@microsoft/fast-foundation": "1.24.6", "@shoelace-style/shoelace": "2.0.0-beta.43", + "firacode": "^5.2.0", "highlight.js": "~11.0.1", - "navigo": "~8.11.1", - "@microsoft/fast-components": "^1.21.6", - "@microsoft/fast-foundation": "1.24.6", - "lodash-es": "4.17.21" + "lodash-es": "4.17.21", + "navigo": "~8.11.1" } } diff --git a/src/website/pnpm-lock.yaml b/src/website/pnpm-lock.yaml index fc23410..6dfe215 100644 --- a/src/website/pnpm-lock.yaml +++ b/src/website/pnpm-lock.yaml @@ -5,6 +5,7 @@ specifiers: '@microsoft/fast-foundation': 1.24.6 '@shoelace-style/shoelace': 2.0.0-beta.43 '@snowpack/plugin-dotenv': ~2.1.0 + firacode: ^5.2.0 firebase-tools: ^9.12.1 highlight.js: ~11.0.1 lodash-es: 4.17.21 @@ -17,16 +18,17 @@ dependencies: '@microsoft/fast-components': 1.21.6_lodash-es@4.17.21 '@microsoft/fast-foundation': 1.24.6_lodash-es@4.17.21 '@shoelace-style/shoelace': 2.0.0-beta.43 + firacode: 5.2.0 highlight.js: 11.0.1 lodash-es: 4.17.21 navigo: 8.11.1 devDependencies: '@snowpack/plugin-dotenv': 2.1.0 - firebase-tools: 9.12.1 + firebase-tools: 9.13.1 markdown-it: 12.0.6 - rollup: 2.50.2 - snowpack: 3.5.1 + rollup: 2.50.6 + snowpack: 3.5.9 packages: @@ -70,22 +72,22 @@ packages: engines: {node: '>=10'} dev: true - /@google-cloud/pubsub/2.13.0: - resolution: {integrity: sha512-DXR/mYbGDUxCoLOT9FhOUrnYcsEEL2am6GMc5GWQf6nqCEH25OxTZJccZ/7xg5UMkDhSWmDcbmtDyAjcPwEN1g==} + /@google-cloud/pubsub/2.14.0: + resolution: {integrity: sha512-pP8pwQ9d+p5KNmccEuwM4W9MM8Z9NP+Zzu3P9ewo/z+obK8mEvh5suC2at60MUWaDQOneTcUICpL6DXLRx957A==} engines: {node: '>=10'} dependencies: '@google-cloud/paginator': 3.0.5 '@google-cloud/precise-date': 2.0.3 '@google-cloud/projectify': 2.1.0 '@google-cloud/promisify': 2.0.3 - '@opentelemetry/api': 0.18.1 - '@opentelemetry/semantic-conventions': 0.18.2 + '@opentelemetry/api': 0.20.0 + '@opentelemetry/semantic-conventions': 0.20.0 '@types/duplexify': 3.6.0 '@types/long': 4.0.1 arrify: 2.0.1 extend: 3.0.2 google-auth-library: 7.1.2 - google-gax: 2.15.0 + google-gax: 2.15.1 is-stream-ended: 0.1.4 lodash.snakecase: 4.1.1 p-defer: 3.0.0 @@ -97,7 +99,7 @@ packages: resolution: {integrity: sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==} engines: {node: ^8.13.0 || >=10.10.0} dependencies: - '@types/node': 15.12.2 + '@types/node': 15.12.4 dev: true /@grpc/proto-loader/0.6.2: @@ -197,8 +199,8 @@ packages: fastq: 1.11.0 dev: false - /@npmcli/git/2.0.9: - resolution: {integrity: sha512-hTMbMryvOqGLwnmMBKs5usbPsJtyEsMsgXwJbmNrsEuQQh1LAIMDU77IoOrwkCg+NgQWl+ySlarJASwM3SutCA==} + /@npmcli/git/2.1.0: + resolution: {integrity: sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==} dependencies: '@npmcli/promise-spawn': 1.3.2 lru-cache: 6.0.0 @@ -247,13 +249,13 @@ packages: read-package-json-fast: 2.0.2 dev: true - /@opentelemetry/api/0.18.1: - resolution: {integrity: sha512-pKNxHe3AJ5T2N5G3AlT9gx6FyF5K2FS9ZNc+FipC+f1CpVF/EY+JHTJ749dnM2kWIgZTbDJFiGMuc0FYjNSCOg==} + /@opentelemetry/api/0.20.0: + resolution: {integrity: sha512-n06MtDYEc2H07S/NTvGMlxF2Ijp0YbNrI/rBgLcxpEh3hxOkPZA12gxlUoZkBHWCZYau2j3b/uL+QFpiQKOjSw==} engines: {node: '>=8.0.0'} dev: true - /@opentelemetry/semantic-conventions/0.18.2: - resolution: {integrity: sha512-+0P+PrP9qSFVaayNdek4P1OAGE+PEl2SsufuHDRmUpOY25Wzjo7Atyar56Trjc32jkNy4lID6ZFT6BahsR9P9A==} + /@opentelemetry/semantic-conventions/0.20.0: + resolution: {integrity: sha512-x40C3vQMttFlnNEfhFwO49jHrY6AoWnntL35TCem3LINr/aw1W0hGhdKY/zweC64CBJEyiHumaae480rqF8eOA==} engines: {node: '>=8.0.0'} dev: true @@ -314,7 +316,7 @@ packages: '@popperjs/core': 2.9.2 '@shoelace-style/animations': 1.1.0 color: 3.1.3 - globby: 11.0.3 + globby: 11.0.4 lit: 2.0.0-rc.2 lit-html: 2.0.0-rc.3 qr-creator: 1.0.0 @@ -328,7 +330,7 @@ packages: /@snowpack/plugin-dotenv/2.1.0: resolution: {integrity: sha512-NvwB+kQuxKheZLWrRvOgXB8i0cXhuIkljbgCn02fRGCIOigPIDk1jZrnn3x9skqqtul/XvW9dNulVi6Fa7CN6g==} dependencies: - dotenv: 8.2.0 + dotenv: 8.6.0 dotenv-expand: 5.1.0 dev: true @@ -353,14 +355,14 @@ packages: /@types/duplexify/3.6.0: resolution: {integrity: sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==} dependencies: - '@types/node': 15.12.2 + '@types/node': 15.12.4 dev: true /@types/glob/7.1.3: resolution: {integrity: sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==} dependencies: '@types/minimatch': 3.0.4 - '@types/node': 15.12.2 + '@types/node': 15.12.4 dev: true /@types/json-schema/7.0.7: @@ -375,8 +377,8 @@ packages: resolution: {integrity: sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==} dev: true - /@types/node/15.12.2: - resolution: {integrity: sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==} + /@types/node/15.12.4: + resolution: {integrity: sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA==} dev: true /@types/trusted-types/1.0.6: @@ -796,8 +798,8 @@ packages: engines: {node: '>= 0.8'} dev: true - /cacache/15.1.0: - resolution: {integrity: sha512-mfx0C+mCfWjD1PnwQ9yaOrwG1ou9FkKnx0SvzUHWdFt7r7GaRtzT+9M8HAvLu62zIHtnpQ/1m93nWNDCckJGXQ==} + /cacache/15.2.0: + resolution: {integrity: sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==} engines: {node: '>= 10'} dependencies: '@npmcli/move-file': 1.1.2 @@ -911,8 +913,8 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /chokidar/3.5.1: - resolution: {integrity: sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==} + /chokidar/3.5.2: + resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==} engines: {node: '>= 8.10.0'} dependencies: anymatch: 3.1.2 @@ -921,7 +923,7 @@ packages: is-binary-path: 2.1.0 is-glob: 4.0.1 normalize-path: 3.0.0 - readdirp: 3.5.0 + readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.2 dev: true @@ -1375,9 +1377,9 @@ packages: engines: {node: '>=6'} dev: true - /dotenv/8.2.0: - resolution: {integrity: sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==} - engines: {node: '>=8'} + /dotenv/8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} dev: true /duplexer2/0.1.4: @@ -1436,7 +1438,7 @@ packages: /encoding/0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} dependencies: - iconv-lite: 0.6.2 + iconv-lite: 0.6.3 dev: true optional: true @@ -1710,8 +1712,8 @@ packages: reusify: 1.0.4 dev: false - /fdir/5.0.0: - resolution: {integrity: sha512-cteqwWMA43lEmgwOg5HSdvhVFD39vHjQDhZkRMlKmeoNPtSSgUw1nUypydiY2upMdGiBFBZvNBDbnoBh0yCzaQ==} + /fdir/5.1.0: + resolution: {integrity: sha512-IgTtZwL52tx2wqWeuGDzXYTnNsEjNLahZpJw30hCQDyVnoHXwY5acNDnjGImTTL1R0z1PCyLw20VAbE5qLic3Q==} dev: true /fecha/4.2.1: @@ -1754,17 +1756,21 @@ packages: unpipe: 1.0.0 dev: true - /firebase-tools/9.12.1: - resolution: {integrity: sha512-izgpgUiG36UwIV12oBu3X8ndACGsxh2cuREnGgTAoTs6P5OC2nEV3riwAak9eQpkuqHfZ6vEuw5ogSbMNqRIgA==} + /firacode/5.2.0: + resolution: {integrity: sha512-Q1SO7vibzYcT+KaohGK0ypGS58zLtO2o2UuiLvngTEhBbHQoZmZ4DAiugj0MNNpeM4jG9gM9NyusVDM3MxYP7A==} + dev: false + + /firebase-tools/9.13.1: + resolution: {integrity: sha512-o8sdTxKtZOG1BJ8SmIHLbwJPkp+C25uUWq7Gcu5+Ksc1obHKKa8dYSH2kEC56gXyoGL5vmGdM8UUDTe7oUy4KA==} engines: {node: '>= 10.13'} hasBin: true dependencies: - '@google-cloud/pubsub': 2.13.0 + '@google-cloud/pubsub': 2.14.0 '@types/archiver': 5.1.0 abort-controller: 3.0.0 archiver: 5.3.0 body-parser: 1.19.0 - chokidar: 3.5.1 + chokidar: 3.5.2 cjson: 0.3.3 cli-color: 1.4.0 cli-table: 0.3.6 @@ -1815,7 +1821,7 @@ packages: uuid: 3.4.0 winston: 3.3.3 winston-transport: 4.4.0 - ws: 7.4.6 + ws: 7.5.0 transitivePeerDependencies: - bufferutil - supports-color @@ -2058,8 +2064,8 @@ packages: ini: 2.0.0 dev: true - /globby/11.0.3: - resolution: {integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==} + /globby/11.0.4: + resolution: {integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==} engines: {node: '>=10'} dependencies: array-union: 2.1.0 @@ -2104,8 +2110,8 @@ packages: - supports-color dev: true - /google-gax/2.15.0: - resolution: {integrity: sha512-jfShUgX1DVu+DiOeAcsT5JbWlLdUnb2FsdWRb+Q/pNz6kNAUbmq8sFLB2uaWjlTxoSGHZLfrt3vJ9lpArzzQPA==} + /google-gax/2.15.1: + resolution: {integrity: sha512-I5j4JRxx1HfZZBXnQs7gUvRHaTqT8XZ6U/QQWI/mDbf05dXP/vLni+ZkDzUh/XHDtIo/MPVkuEUhkwWwi+vwTg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -2306,8 +2312,8 @@ packages: safer-buffer: 2.1.2 dev: true - /iconv-lite/0.6.2: - resolution: {integrity: sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==} + /iconv-lite/0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 @@ -2432,13 +2438,13 @@ packages: ci-info: 2.0.0 dev: true - /is-core-module/2.2.0: - resolution: {integrity: sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==} + /is-core-module/2.4.0: + resolution: {integrity: sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==} dependencies: has: 1.0.3 - /is-docker/2.1.1: - resolution: {integrity: sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==} + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true dev: true @@ -2544,7 +2550,7 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} dependencies: - is-docker: 2.1.1 + is-docker: 2.2.1 dev: true /is-yarn-global/0.3.0: @@ -2954,7 +2960,31 @@ packages: engines: {node: '>= 10'} dependencies: agentkeepalive: 4.1.4 - cacache: 15.1.0 + cacache: 15.2.0 + http-cache-semantics: 4.1.0 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.0 + is-lambda: 1.0.1 + lru-cache: 6.0.0 + minipass: 3.1.3 + minipass-collect: 1.0.2 + minipass-fetch: 1.3.3 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + promise-retry: 2.0.1 + socks-proxy-agent: 5.0.0 + ssri: 8.0.1 + transitivePeerDependencies: + - supports-color + dev: true + optional: true + + /make-fetch-happen/9.0.3: + resolution: {integrity: sha512-uZ/9Cf2vKqsSWZyXhZ9wHHyckBrkntgbnqV68Bfe8zZenlf7D6yuGMXvHZQ+jSnzPkjosuNP1HGasj1J4h8OlQ==} + engines: {node: '>= 10'} + dependencies: + agentkeepalive: 4.1.4 + cacache: 15.2.0 http-cache-semantics: 4.1.0 http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.0 @@ -2965,6 +2995,7 @@ packages: minipass-fetch: 1.3.3 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 + negotiator: 0.6.2 promise-retry: 2.0.1 socks-proxy-agent: 5.0.0 ssri: 8.0.1 @@ -3337,8 +3368,8 @@ packages: resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==} dev: true - /npm-package-arg/8.1.2: - resolution: {integrity: sha512-6Eem455JsSMJY6Kpd3EyWE+n5hC+g9bSyHr9K9U2zqZb7+02+hObQ2c0+8iDk/mNF+8r1MhY44WypKJAkySIYA==} + /npm-package-arg/8.1.5: + resolution: {integrity: sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==} engines: {node: '>=10'} dependencies: hosted-git-info: 4.0.2 @@ -3362,21 +3393,20 @@ packages: dependencies: npm-install-checks: 4.0.0 npm-normalize-package-bin: 1.0.1 - npm-package-arg: 8.1.2 + npm-package-arg: 8.1.5 semver: 7.3.5 dev: true - /npm-registry-fetch/10.1.2: - resolution: {integrity: sha512-KsM/TdPmntqgBFlfsbkOLkkE9ovZo7VpVcd+/eTdYszCrgy5zFl5JzWm+OxavFaEWlbkirpkou+ZYI00RmOBFA==} + /npm-registry-fetch/11.0.0: + resolution: {integrity: sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==} engines: {node: '>=10'} dependencies: - lru-cache: 6.0.0 - make-fetch-happen: 8.0.14 + make-fetch-happen: 9.0.3 minipass: 3.1.3 minipass-fetch: 1.3.3 minipass-json-stream: 1.0.1 minizlib: 2.1.2 - npm-package-arg: 8.1.2 + npm-package-arg: 8.1.5 transitivePeerDependencies: - supports-color dev: true @@ -3455,7 +3485,7 @@ packages: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} dependencies: - is-docker: 2.1.1 + is-docker: 2.2.1 is-wsl: 2.2.0 dev: true @@ -3552,25 +3582,25 @@ packages: semver: 6.3.0 dev: true - /pacote/11.3.3: - resolution: {integrity: sha512-GQxBX+UcVZrrJRYMK2HoG+gPeSUX/rQhnbPkkGrCYa4n2F/bgClFPaMm0nsdnYrxnmUy85uMHoFXZ0jTD0drew==} + /pacote/11.3.4: + resolution: {integrity: sha512-RfahPCunM9GI7ryJV/zY0bWQiokZyLqaSNHXtbNSoLb7bwTvBbJBEyCJ01KWs4j1Gj7GmX8crYXQ1sNX6P2VKA==} engines: {node: '>=10'} hasBin: true dependencies: - '@npmcli/git': 2.0.9 + '@npmcli/git': 2.1.0 '@npmcli/installed-package-contents': 1.0.7 '@npmcli/promise-spawn': 1.3.2 '@npmcli/run-script': 1.8.5 - cacache: 15.1.0 + cacache: 15.2.0 chownr: 2.0.0 fs-minipass: 2.1.0 infer-owner: 1.0.4 minipass: 3.1.3 mkdirp: 1.0.4 - npm-package-arg: 8.1.2 + npm-package-arg: 8.1.5 npm-packlist: 2.2.2 npm-pick-manifest: 6.1.1 - npm-registry-fetch: 10.1.2 + npm-registry-fetch: 11.0.0 promise-retry: 2.0.1 read-package-json-fast: 2.0.2 rimraf: 3.0.2 @@ -3600,8 +3630,8 @@ packages: engines: {node: '>=8'} dev: true - /path-parse/1.0.6: - resolution: {integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==} + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} /path-to-regexp/0.1.7: resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} @@ -3622,11 +3652,6 @@ packages: resolution: {integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=} dev: true - /picomatch/2.2.2: - resolution: {integrity: sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==} - engines: {node: '>=8.6'} - dev: true - /picomatch/2.3.0: resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==} engines: {node: '>=8.6'} @@ -3706,7 +3731,7 @@ packages: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.1 - '@types/node': 15.12.2 + '@types/node': 15.12.4 long: 4.0.0 dev: true @@ -3891,8 +3916,8 @@ packages: minimatch: 3.0.4 dev: true - /readdirp/3.5.0: - resolution: {integrity: sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==} + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.0 @@ -3953,15 +3978,15 @@ packages: /resolve/1.19.0: resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} dependencies: - is-core-module: 2.2.0 - path-parse: 1.0.6 + is-core-module: 2.4.0 + path-parse: 1.0.7 dev: false /resolve/1.20.0: resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==} dependencies: - is-core-module: 2.2.0 - path-parse: 1.0.6 + is-core-module: 2.4.0 + path-parse: 1.0.7 dev: true /responselike/1.0.2: @@ -4019,8 +4044,8 @@ packages: fsevents: 2.1.3 dev: true - /rollup/2.50.2: - resolution: {integrity: sha512-Ra5JkxSiZPZZFnvE68KWtlrLnZGg5LNaV1n1esq4ch69P7ReeoRVlrTuL/k+L/GJfcowA5An0BEhEq2Hfzwl6w==} + /rollup/2.50.6: + resolution: {integrity: sha512-6c5CJPLVgo0iNaZWWliNu1Kl43tjP9LZcp6D/tkf2eLH2a9/WeHxg9vfTFl8QV/2SOyaJX37CEm9XuGM0rviUg==} engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: @@ -4196,18 +4221,18 @@ packages: engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} dev: true - /snowpack/3.5.1: - resolution: {integrity: sha512-YOpC3hpGSzFOKgbHfMmWmJ1KYEtdBWkbUUdT0H3E1fsc73qRv97wskNkVaeNKtr/yrImR5+KHUvxcWY6jgHVtw==} + /snowpack/3.5.9: + resolution: {integrity: sha512-Rajenx5DRDiMKC+GiU1vMP+tcjge9bAe35fGsPdhkTtIwRkV3u4he1TfiwTh8F1hcOcG5IzLe8jqGM9sBANtpw==} engines: {node: '>=10.19.0'} hasBin: true dependencies: cli-spinners: 2.6.0 default-browser-id: 2.0.0 esbuild: 0.9.7 - fdir: 5.0.0 + fdir: 5.1.0 open: 7.4.2 - pacote: 11.3.3 - picomatch: 2.2.2 + pacote: 11.3.4 + picomatch: 2.3.0 resolve: 1.20.0 rollup: 2.37.1 optionalDependencies: @@ -4890,8 +4915,8 @@ packages: typedarray-to-buffer: 3.1.5 dev: true - /ws/7.4.6: - resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} + /ws/7.5.0: + resolution: {integrity: sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==} engines: {node: '>=8.3.0'} peerDependencies: bufferutil: ^4.0.1 diff --git a/src/website/snowpack.config.js b/src/website/snowpack.config.js index 6545e27..f26694c 100644 --- a/src/website/snowpack.config.js +++ b/src/website/snowpack.config.js @@ -5,7 +5,10 @@ module.exports = { public: { url: '/', static: true }, src: { url: '/dist' }, 'node_modules/@shoelace-style/shoelace/dist/assets': { url: '/shoelace/assets', static: true }, - '../Sutil.Shoelace': { url: '/Sutil.Shoelace', static: true } + 'node_modules/firacode/distr/woff': { url: '/woff', static: true }, + 'node_modules/firacode/distr/woff2': { url: '/woff2', static: true }, + '../Sutil.Shoelace': { url: '/Sutil.Shoelace', static: true }, + '../Sutil.Fast': { url: '/Sutil.Fast', static: true }, }, plugins: [ '@snowpack/plugin-dotenv', diff --git a/src/website/src/App.fs b/src/website/src/App.fs index 3f2902d..19c1d43 100644 --- a/src/website/src/App.fs +++ b/src/website/src/App.fs @@ -1,13 +1,19 @@ module App +open Browser.Dom +open Browser.Types +open Fable.Core +open Fable.Core.DynamicExtensions open Sutil open Sutil.DOM open Sutil.Attr open Sutil.Styling open Sutil.Shoelace +open Sutil.Fast open Types open Router open Components +open Sutil.Fast.FastDesignSystemProvider type State = { page: Page; navOpen: bool } @@ -15,6 +21,11 @@ type Msg = | NavigateTo of Page | ToggleNav +[] +let registerThemeEventListener (onThemeChange: bool -> unit) = jsNative + +[] +let getPalette (color: string) = jsNative let init () : State * Cmd = { page = Home; navOpen = false }, Cmd.none @@ -33,8 +44,29 @@ let navigateTo (dispatch: Dispatch) (page: Page) = let view () = let state, dispatch = Store.makeElmish init update ignore () + let theme = + Store.make + {| luminance = 1. + backgroundColor = "#E1E1E1" |} + let navigateTo = navigateTo dispatch + let changeTheme isDark = + if isDark then + document.body.classList.add ("sl-theme-dark") + + theme + <~ {| luminance = 0.23 + backgroundColor = "#1E1E1E" |} + else + document.body.classList.remove ("sl-theme-dark") + + theme + <~ {| luminance = 1. + backgroundColor = "#FFFFFF" |} + + registerThemeEventListener changeTheme + Router.on "/" (fun _ -> navigateTo Home) |> ignore Router.on @@ -77,66 +109,88 @@ let view () = navigateTo page + + let background = + theme .> (fun theme -> theme.backgroundColor) + + let luminance = theme .> (fun theme -> theme.luminance) + + let setColorPallete (e: Event) = + let el = + // We'll cast this heare for clarity although, it is not necessary + e.target :?> FastDesignSystemProvider + // accentPallete is not an attribute hence why we'll assign it dynamically + el.["accentPalette"] <- getPalette "#0ea5e9" + Html.app [ disposeOnUnmount [ state ] - class' "app-content" - Html.nav [ - class' "app-nav" - Html.section [ - Shoelace.SlButton [ - type' "text" - text "Sutil.Shoelace" - onClick (fun _ -> Router.navigate "/" None) [] - ] - Shoelace.SlButton [ - type' "text" - text "Shoelace" - Shoelace.SlIcon [ - Attr.name "book" - Attr.slot "prefix" + Fast.FastDesignSystemProvider [ + class' "main-provider" + onMount setColorPallete [] + Attr.custom ("use-defaults", "true") + Attr.custom ("density", "1") + Attr.custom ("corner-radius", "5") + // workaround we usually would bind to the attribute not the property + Bind.attr ("backgroundColor", background) + Bind.attr ("baseLayerLuminance", luminance) + Html.nav [ + class' "app-nav" + Html.section [ + Shoelace.SlButton [ + type' "text" + text "Sutil.Shoelace" + onClick (fun _ -> Router.navigate "/" None) [] ] - onClick (fun _ -> Router.navigate "shoelace/docs/index" None) [] - ] - Shoelace.SlButton [ - type' "text" - text "Documentation" - Shoelace.SlIcon [ - Attr.name "book" - Attr.slot "prefix" + Shoelace.SlButton [ + type' "text" + text "Shoelace" + Shoelace.SlIcon [ + Attr.name "book" + Attr.slot "prefix" + ] + onClick (fun _ -> Router.navigate "shoelace/docs/index" None) [] + ] + Shoelace.SlButton [ + type' "text" + text "Fast" + Shoelace.SlIcon [ + Attr.name "book" + Attr.slot "prefix" + ] + onClick (fun _ -> Router.navigate "fast/docs/index" None) [] ] - onClick (fun _ -> Router.navigate "fast/docs/index" None) [] ] - ] - Html.section [ - class' "show-on-mobile" - Shoelace.SlButton [ - type' "text" - text "Menu" - Shoelace.SlIcon [ - Attr.name "list" - Attr.slot "prefix" + Html.section [ + class' "show-on-mobile" + Shoelace.SlButton [ + type' "text" + text "Menu" + Shoelace.SlIcon [ + Attr.name "list" + Attr.slot "prefix" + ] + onClick (fun _ -> dispatch ToggleNav) [] ] - onClick (fun _ -> dispatch ToggleNav) [] ] ] - ] - Html.main [ - Desktop.Sidenav - Mobile.Sidenav [ - Bind.attr ("open", (state .> fun state -> state.navOpen)) - on "sl-hide" (fun _ -> dispatch ToggleNav) [] - ] + Html.main [ + Desktop.Sidenav + Mobile.Sidenav [ + Bind.attr ("open", (state .> fun state -> state.navOpen)) + on "sl-hide" (fun _ -> dispatch ToggleNav) [] + ] - bindFragment state - <| fun state -> - match state.page with - | Home -> Pages.Home.view () - | Docs (library, page) -> Pages.Docs.view library page - | Library library -> - match library with - | Shoelace -> Pages.Shoelace.view () - | Fast -> Pages.Fast.view () - | NotFound -> Html.article [ text "NotFound" ] + bindFragment state + <| fun state -> + match state.page with + | Home -> Pages.Home.view () + | Docs (library, page) -> Pages.Docs.view library page + | Library library -> + match library with + | Shoelace -> Pages.Shoelace.view () + | Fast -> Pages.Fast.view () + | NotFound -> Html.article [ text "NotFound" ] + ] ] ] diff --git a/src/website/src/Main.fs b/src/website/src/Main.fs index 8de3a67..e3aa027 100644 --- a/src/website/src/Main.fs +++ b/src/website/src/Main.fs @@ -4,14 +4,52 @@ open Sutil open Sutil.DOM open Fable.Core open Fable.Core.JsInterop +open Sutil.Fast.FastDesignSystemProvider +open Sutil.Fast.FastButton +open Sutil.Fast.FastAnchor +// CSS Imports importSideEffects "@shoelace-style/shoelace/dist/themes/base.css" importSideEffects "@shoelace-style/shoelace/dist/themes/dark.css" - -importSideEffects "./styles.css" -importSideEffects "@shoelace-style/shoelace/dist/shoelace.js" importSideEffects "highlight.js/styles/nord.css" +importSideEffects "firacode/distr/fira_code.css" +importSideEffects "./styles.css" + +// JS Imports + +importSideEffects "@shoelace-style/shoelace/dist/components/alert/alert.js" +importSideEffects "@shoelace-style/shoelace/dist/components/button/button.js" + +importSideEffects + "@shoelace-style/shoelace/dist/components/checkbox/checkbox.js" + +importSideEffects "@shoelace-style/shoelace/dist/components/icon/icon.js" +importSideEffects "@shoelace-style/shoelace/dist/components/menu/menu.js" + +importSideEffects + "@shoelace-style/shoelace/dist/components/menu-divider/menu-divider.js" + +importSideEffects + "@shoelace-style/shoelace/dist/components/menu-item/menu-item.js" + +importSideEffects "@shoelace-style/shoelace/dist/components/drawer/drawer.js" +importSideEffects "@shoelace-style/shoelace/dist/components/include/include.js" + +importSideEffects + "@shoelace-style/shoelace/dist/components/dropdown/dropdown.js" + +importSideEffects "./Theme.js" + +let private FASTDesignSystemProvider = + importMember "@microsoft/fast-components" + +let private FASTButton = + importMember "@microsoft/fast-components" + +let private FASTAnchor = + importMember "@microsoft/fast-components" + [] diff --git a/src/website/src/Pages/Home.fs b/src/website/src/Pages/Home.fs index ca81f0b..21f3f1a 100644 --- a/src/website/src/Pages/Home.fs +++ b/src/website/src/Pages/Home.fs @@ -2,4 +2,54 @@ module Pages.Home open Sutil -let view () = Html.article [ text "Home" ] +open Sutil.Shoelace +open Sutil.Fast +open Sutil.Styling +open Sutil.DOM +open Sutil.Attr + +open type Feliz.length + +let view () = + Html.article [ + Html.section [ + Shoelace.SlInclude [ + Attr.src "/dist/docs/home.html" + ] + ] + Html.section [ + class' "row" + Fast.FastAnchor [ + Attr.href "https://fast.design" + Attr.target "_blank" + Attr.custom ("appearance", "outline") + text "Get to know more about FAST" + ] + Shoelace.SlButton [ + Attr.target "_blank" + Attr.href "https://shoelace.style" + text "Get to know more about Shoelace" + ] + ] + Html.section [ + Shoelace.SlInclude [ + Attr.src "/dist/docs/home-2.html" + ] + ] + ] + |> withStyle [ + rule + "article" + [ Css.marginLeft Feliz.length.auto + Css.marginRight Feliz.length.auto + Css.marginTop (Feliz.length.em 2) + Css.padding (Feliz.length.em 2) + Css.paddingTop 0 ] + rule + "section.row" + [ Css.marginTop (em 2) + Css.marginBottom (em 2) + Css.displayFlex + Css.custom ("justify-content", "space-evenly") + Css.alignItemsCenter ] + ] diff --git a/src/website/src/Routes.fs b/src/website/src/Routes.fs index b563f12..bf55dff 100644 --- a/src/website/src/Routes.fs +++ b/src/website/src/Routes.fs @@ -27,6 +27,14 @@ let routes = href = "#/shoelace/docs/getting-started" library = Shoelace category = Guides } + { name = "Getting Started" + href = "#/fast/docs/getting-started" + library = Fast + category = Guides } + { name = "Themes" + href = "#/fast/docs/themes" + library = Fast + category = Guides } { name = "How to use components" href = "#/shoelace/docs/components" library = Shoelace diff --git a/src/website/src/Theme.js b/src/website/src/Theme.js new file mode 100644 index 0000000..a284c02 --- /dev/null +++ b/src/website/src/Theme.js @@ -0,0 +1,11 @@ +import { parseColorString, createColorPalette } from '@microsoft/fast-components'; +const prefersDarkQuery = window.matchMedia('(prefers-color-scheme: dark)'); +const isDark = () => prefersDarkQuery.matches; +export function registerThemeEventListener(cb) { + cb(isDark()); + prefersDarkQuery.addEventListener('change', () => cb(isDark())); +} + +export function getPalette(color) { + return createColorPalette(parseColorString(color)); +} \ No newline at end of file diff --git a/src/website/src/Types.fs b/src/website/src/Types.fs index ecc6f09..8f198c2 100644 --- a/src/website/src/Types.fs +++ b/src/website/src/Types.fs @@ -6,6 +6,10 @@ type Page = | Docs of library: string * docSite: string | NotFound +type Theme = + | Light + | Dark + type DocsUrlData = { library: string page: string option } diff --git a/src/website/src/docs/fast/getting-started.md b/src/website/src/docs/fast/getting-started.md new file mode 100644 index 0000000..2ff8c75 --- /dev/null +++ b/src/website/src/docs/fast/getting-started.md @@ -0,0 +1,73 @@ +[Javascript Modules]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules +[femto]: https://github.com/Zaid-Ajaj/Femto +[Theming]: #/fast/docs/theming + +# Getting Started + +```sh +dotnet add package Sutil.Fast --version +pnpm install @microsoft/fast-components@ @microsoft/fast-foundation lodash-es # or npm install @microsoft/Fast@ +``` +If you are using [femto] then you just need to do + +- `femto install Sutil.Fast --version ` + +# After Install + +> Please feel free to also check Fast's [documentation](https://www.fast.design/docs/introduction/). + + +Once you're done installing Sutil.Fast, you should be able to do the following: + +```fsharp +open Sutil.Fast + +Fast.FastDesignSystemProvider [ + Attr.custom ("use-defaults", "true") + Attr.style "padding: 1em" + Fast.FastButton [ + Attr.custom("appearance","primary") + text "Hello, there!" + ] +] +``` + +but that doesn't mean that you will see yout components right away, Fast uses [Javascript Modules] to load its components. + +To do that we need to load the components in one of the following ways in your `Main.fs` or entry point file of your Sutil application + +```fsharp +// Main.fs or App.fs +importSideEffects "@microsoft/fast-components" +``` +This will load all the Fast components to the browser and then you should be able to see the following + + + + Hello, there! + + +Fast uses a design system provider that allows you to easily theme your application or parts of your application as much as you desire, if you want to learn more about that check + +Fast Themes + +For development purposes this should be enough. If you want to optimize for production I'd encourage you to keep reading the next section +## Cherry-pick components + +> Please feel free to also check Fast's [documentation](https://www.fast.design/docs/components/getting-started#from-npm) + + +To optimize your bundle sizes and prevent unused code ending up in your user's storage, then cherry-picking is the ideal option since you will only load and bundle the components you're using. + +```fsharp +open Sutil.Fast.FastDesignSystemProvider +open Sutil.Fast.FastButton +open Sutil.Fast.FastAnchor + +let private FASTDesignSystemProvider = importMember"@microsoft/fast-components" +let private FASTButton = importMember"@microsoft/fast-components" +let private FASTAnchor = importMember"@microsoft/fast-components" +``` + +This will help your bundler to prevent tree-shaking the elements that you're using. +Now you're ready to start doing some Sutil.Fast! \ No newline at end of file diff --git a/src/website/src/docs/fast/themes.md b/src/website/src/docs/fast/themes.md new file mode 100644 index 0000000..5030cee --- /dev/null +++ b/src/website/src/docs/fast/themes.md @@ -0,0 +1,217 @@ +[Themes]: https://www.fast.design/docs/design-systems/overview + +# FAST Themes + +> Please also check FAST documentation on [Themes] for more and better information. + +Fast includes a system design provider which allows you to write theming in your website from the start. + +In the case of `Sutil.Fast` once you [have imported](#/fast/docs/getting-started) the required scripts you can do the following + +```fsharp +open Sutil.Fast + +Fast.FastDesignSystemProvider [ + // initialize all of the properties + Attr.custom ("use-defaults", "true") + Attr.custom ("density", "1") + Attr.custom ("corner-radius", "5") + Attr.custom ("background-color", "#000000") + Attr.custom ("base-layer-luminance", "0.23") + + Fast.FastButton [ + Attr.custom("appearance", "accent") + text "Hey there!" + ] +] + +``` +that will give you a dark style with the default accent + + +Hey there! + + + +# Accent color pallete + +> Please also note that FAST uses a lot of javascript for creating custom design systems, so in those cases you are advised to simply add a javascript file for interop (unless you have the time to create bindings for the javascript code in the FAST library) + + + +This part is not obligatory but it might be the easiest way to do it until there's a bindings package for the javascript part of FAST +```js +import { parseColorString, createColorPalette } from 'https://unpkg.com/@microsoft/fast-components'; + +// generate a new color palette for the color you chose +export function getPalette(color) { + return createColorPalette(parseColorString(color)); +} +``` + + +```fsharp +open Browser.Types + +open Fable.Core +open Fable.Core.DynamicExtensions + +open Sutil.Fast +open Sutil.Fast.FastDesignSystemProvider + +[] +let getPalette (color: string) = jsNative + +let setColorPallete (e: Event) = + let el = + // We'll cast this heare for clarity although, it is not necessary + e.target :?> FastDesignSystemProvider + // accentPallete is not an attribute hence why we'll assign it dynamically + el.["accentPalette"] <- getPalette "#0ea5e9" + +let view() = + Fast.FastDesignSystemProvider [ + // when the component is mounted set the collor palette + onMount setColorPallete [] + // initialize all of the properties + Attr.custom ("use-defaults", "true") + // set custom values for existing attributes + Attr.custom ("density", "1") + Attr.custom ("corner-radius", "5") + Attr.custom ("background-color", "#000000") + Attr.custom ("base-layer-luminance", "0.23") + + Fast.FastButton [ + Attr.custom("appearance", "accent") + text "Hey there!" + ] + ] +``` +That should look like this: + + +Hey there! + + + + +# Dark/Light Mode + +Supporting Light and Dark modes is not too hard and should be simple to do. for that we just need to listen for the media query change, add a store and register a callback to react to those changes. + +Let's add a few things to our JS file + +```js +import { parseColorString, createColorPalette } from 'https://unpkg.com/@microsoft/fast-components'; + +const prefersDarkQuery = window.matchMedia('(prefers-color-scheme: dark)'); +const isDark = () => prefersDarkQuery.matches; + +export function registerThemeEventListener(cb) { + cb(isDark()); + prefersDarkQuery.addEventListener('change', () => cb(isDark())); +} + +export function getPalette(color) { + return createColorPalette(parseColorString(color)); +} +``` + +```fsharp +open Browser.Types + +open Fable.Core +open Fable.Core.DynamicExtensions +open Sutil +open Sutil.Fast +open Sutil.Fast.FastDesignSystemProvider + + +[] +let registerThemeEventListener (onThemeChange: bool -> unit) = jsNative + +[] +let getPalette (color: string) = jsNative + +let setColorPallete (e: Event) = + let el = + // We'll cast this heare for clarity although, it is not necessary + e.target :?> FastDesignSystemProvider + // accentPallete is not an attribute hence why we'll assign it dynamically + el.["accentPalette"] <- getPalette "#0ea5e9" + +let changeTheme isDark = + // theme <~ is the equivalent to + // Store.set {| ...values ... |} theme + if isDark then + theme + <~ {| luminance = 0.23 + backgroundColor = "#1E1E1E" |} + else + theme + <~ {| luminance = 1. + backgroundColor = "#FFFFFF" |} +// register our callback +registerThemeEventListener changeTheme + +let background = + // theme .> (fun theme -> theme.backgroundColor) is the equivalent to + // Store.map (fun theme -> theme.backgroundColor) theme + theme .> (fun theme -> theme.backgroundColor) + +let luminance = theme .> (fun theme -> theme.luminance) + +let view() = + let theme = + Store.make + // Initial values for your theme + {| luminance = 1. + backgroundColor = "#1E1E1E" |} + Fast.FastDesignSystemProvider [ + // when the component is mounted set the collor palette + onMount setColorPallete [] + // initialize all of the properties + Attr.custom ("use-defaults", "true") + // set custom values for existing attributes + Attr.custom ("density", "1") + Attr.custom ("corner-radius", "5") + // workaround we usually would bind to the attribute not the property + // e.g Bind.attr ("background-color", background) + Bind.attr ("backgroundColor", background) + Bind.attr ("baseLayerLuminance", luminance) + + Fast.FastButton [ + Attr.custom("appearance", "accent") + text "Hey there!" + ] + ] +``` + +That's precisely how this website is configured right now! for the sample we'll inver the colors just to show that you can use multiple providers and have multiple sections with different themes + + +Hey there! + + + diff --git a/src/website/src/docs/getting-started.md b/src/website/src/docs/getting-started.md new file mode 100644 index 0000000..c04e7b9 --- /dev/null +++ b/src/website/src/docs/getting-started.md @@ -0,0 +1,133 @@ +[Javascript Modules]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules +[femto]: https://github.com/Zaid-Ajaj/Femto + +# Getting Started + +```sh +dotnet add package Sutil.Shoelace --version +pnpm install @shoelace-style/shoelace@ # or npm install @shoelace-style/shoelace@ +``` +If you are using [femto] then you just need to do + +- `femto install Sutil.Shoelace --version ` + +# After Install + +> Please feel free to also check shoelace's [documentation](https://shoelace.style/getting-started/installation). + + +Once you're done installing Sutil.Shoelace, you should be able to do the following: + +```fsharp +open Sutil.Shoelace + +Shoelace.SlButton [ + type' "primary" + text "Hello, there!" +] +``` + +but that doesn't mean that you will see yout components right away, Shoelace uses [Javascript Modules] to load its components. + +To do that we need to load the components in one of the following ways in your `Main.fs` or entry point file of your Sutil application + +```fsharp +// Main.fs or App.fs + +importSideEffects "@shoelace-style/shoelace/dist/themes/base.css" +// In case you want to support a dark theme check the guide at +// https://shoelace.style/getting-started/themes?id=dark-mode +// importSideEffects "@shoelace-style/shoelace/dist/themes/dark.css" + +importSideEffects "@shoelace-style/shoelace.js" +``` +This will load all the shoelace components to the browserand then you should be able to see the following + +Hello, there! + +For development purposes this should be enough. If you want to optimize for production I'd encourage you to keep reading the next section +## Cherry-pick components + +> Please feel free to also check shoelace's [documentation](https://shoelace.style/getting-started/installation?id=bundling) + + +To optimize your bundle sizes and prevent unused code ending up in your user's storage, then cherry-picking is the ideal option since you will only load and bundle the components you're using. + +```fsharp + +importSideEffects "@shoelace-style/shoelace/dist/components/button/button.js" + +importSideEffects "@shoelace-style/shoelace/dist/components/icon/icon.js" +``` + +then if you try the following: +```fsharp +Shoelace.SlButton [ + Shoelace.SlIcon [ + Attr.slot "prefix" + Attr.name "info-circle" + ] +] +``` + it should look like this + + + + +If you wonder why the icon is not showing it means that you're not serving the icons statically + +you can fix that by selecting where are you going to mount the icon assets with your bundler + +```fsharp +[] +let setBasePath (path: string) : unit = jsNative + +setBasePath "shoelace" +``` + + +### Snowpack +In the case of snowpack its quite simple + +```javascript +/** @type {import("snowpack").SnowpackUserConfig } */ +module.exports = { + + mount: { + public: { url: '/', static: true }, + src: { url: '/dist' }, + // tell snowpack to mount your assets in "shoelace/assets" + 'node_modules/@shoelace-style/shoelace/dist/assets': { url: '/shoelace/assets', static: true } + /* ... the rest of your config */ + }, + /* ... the rest of your config */ +}; +``` + +### Webpack +In the case of webpack we can use the copy plugin +```javascript +module.exports = { + /* ... the rest of your config ... */ + plugins: [ + new CopyPlugin({ + patterns: [ + // Copy Shoelace assets to dist/shoelace + { + from: path.resolve(__dirname, 'node_modules/@shoelace-style/shoelace/dist/assets'), + to: path.resolve(__dirname, 'dist/shoelace/assets') + } + ] + }) + /* ... the rest of your config ... */ + ] +}; +``` + +Once we've done that either with webpack or snowpack our button will show like this + + + Info + + +Now you're ready to start doing some Sutil.Shoelace! \ No newline at end of file diff --git a/src/website/src/docs/home-2.md b/src/website/src/docs/home-2.md new file mode 100644 index 0000000..457fe11 --- /dev/null +++ b/src/website/src/docs/home-2.md @@ -0,0 +1,3 @@ +If you take a quick inspection in the browser devloper tools you'll find that both libraries work side by side, in fact the whole site has both libraries' elements scattered! and this doesn't really impact on the performance as long as you cherry pick components (check `getting started` on your favorite library). + +If you want to see more details on how these libraries look in F# take a look at the [website docs](https://github.com/AngelMunoz/Sutil.Generator/tree/master/src/website)! \ No newline at end of file diff --git a/src/website/src/docs/home.md b/src/website/src/docs/home.md index e69de29..f649eba 100644 --- a/src/website/src/docs/home.md +++ b/src/website/src/docs/home.md @@ -0,0 +1,19 @@ +[Sutil]: https://github.com/davedawkins/Sutil +[Sutil.Generator]: https://github.com/AngelMunoz/Sutil.Generator +[Web Components]: https://developer.mozilla.org/en-US/docs/Web/Web_Components +[Shoelace]: https://shoelace.style/ +[Fast]: https://fast.design/ + +# Sutil.Generator + +[Sutil.Generator] is a project that aims to bring the goodness of [Web Components] to F# thanks to [Sutil] + +Since Sutil is a pure F# And JS framework without other dependencies rather than Fable.Core and Feliz.Engine it allows itself to be quite interoperable with the rest of the web + +In this page we're using HTML elements, [Shoelace], and [FAST] components, all in the same place they don't fight each other, they just work completely fine + +See them working side by side below 👇🏽 + + + + \ No newline at end of file diff --git a/src/website/src/styles.css b/src/website/src/styles.css index 1d2d664..add1b68 100644 --- a/src/website/src/styles.css +++ b/src/website/src/styles.css @@ -118,3 +118,6 @@ article.doc-page sl-include { } } +pre, code { + font-family: 'Fira Code', monospace; +} \ No newline at end of file