From ab7b60cd35aa59a770e6f1ae8e93932431983d13 Mon Sep 17 00:00:00 2001 From: Juan Valencia Date: Fri, 20 Dec 2019 11:18:23 +0100 Subject: [PATCH] =?UTF-8?q?Docs=20initial=20website=20=F0=9F=96=A8=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 13 ++ docs/Gemfile | 3 + docs/Gemfile.lock | 65 +++++++++ docs/README.md | 37 +++-- docs/_config.yml | 21 +++ docs/_data/menu.yml | 9 ++ docs/_data/sidebar.yml | 32 +++++ docs/_includes/_doc.html | 14 ++ docs/_includes/_footer.html | 22 +++ docs/_includes/_head-docs.html | 29 ++++ docs/_includes/_header.html | 13 ++ docs/_includes/_main.html | 13 ++ docs/_includes/_nav.html | 32 +++++ docs/_includes/_sidebar.html | 100 +++++++++++++ docs/_layouts/docs.html | 8 ++ docs/_sass/base/_base.scss | 64 +++++++++ docs/_sass/base/_helpers.scss | 10 ++ docs/_sass/base/_reset.scss | 141 ++++++++++++++++++ docs/_sass/components/_button.scss | 47 ++++++ docs/_sass/components/_code.scss | 23 +++ docs/_sass/components/_doc.scss | 97 +++++++++++++ docs/_sass/components/_footer.scss | 85 +++++++++++ docs/_sass/components/_header.scss | 109 ++++++++++++++ docs/_sass/components/_main.scss | 51 +++++++ docs/_sass/components/_nav.scss | 141 ++++++++++++++++++ docs/_sass/components/_sidebar-menu.scss | 115 +++++++++++++++ docs/_sass/components/_sidebar.scss | 89 ++++++++++++ docs/_sass/components/_table.scss | 29 ++++ docs/_sass/utils/_mixins.scss | 53 +++++++ docs/_sass/utils/_variables.scss | 74 ++++++++++ docs/_sass/vendors/highlight/dracula.scss | 167 ++++++++++++++++++++++ docs/css/docs.scss | 23 +++ docs/docs/README.md | 20 +++ docs/{ => docs}/db.md | 6 + docs/{ => docs}/grpc.md | 6 + docs/{ => docs}/intro.md | 6 + docs/{ => docs}/middleware.md | 6 + docs/{ => docs}/registry.md | 6 + docs/{ => docs}/rpc.md | 6 + docs/{ => docs}/schema.md | 6 + docs/{ => docs}/stream.md | 6 + docs/{ => docs}/transformer.md | 6 + docs/img/favicon.png | Bin 0 -> 2790 bytes docs/img/header-image.svg | 99 +++++++++++++ docs/img/main-feature-primary.svg | 75 ++++++++++ docs/img/main-feature-secondary.svg | 110 ++++++++++++++ docs/img/main-feature-tertiary.svg | 55 +++++++ docs/img/nav-brand-white.svg | 9 ++ docs/img/nav-brand.svg | 9 ++ docs/img/nav-icon-close.svg | 12 ++ docs/img/nav-icon-open.svg | 13 ++ docs/img/sidebar-icon-open.svg | 11 ++ docs/js/docs.js | 162 +++++++++++++++++++++ docs/js/main.js | 31 ++++ 54 files changed, 2378 insertions(+), 11 deletions(-) create mode 100755 docs/Gemfile create mode 100755 docs/Gemfile.lock create mode 100755 docs/_config.yml create mode 100755 docs/_data/menu.yml create mode 100755 docs/_data/sidebar.yml create mode 100644 docs/_includes/_doc.html create mode 100755 docs/_includes/_footer.html create mode 100644 docs/_includes/_head-docs.html create mode 100755 docs/_includes/_header.html create mode 100755 docs/_includes/_main.html create mode 100755 docs/_includes/_nav.html create mode 100755 docs/_includes/_sidebar.html create mode 100755 docs/_layouts/docs.html create mode 100755 docs/_sass/base/_base.scss create mode 100644 docs/_sass/base/_helpers.scss create mode 100755 docs/_sass/base/_reset.scss create mode 100644 docs/_sass/components/_button.scss create mode 100755 docs/_sass/components/_code.scss create mode 100755 docs/_sass/components/_doc.scss create mode 100755 docs/_sass/components/_footer.scss create mode 100755 docs/_sass/components/_header.scss create mode 100755 docs/_sass/components/_main.scss create mode 100755 docs/_sass/components/_nav.scss create mode 100644 docs/_sass/components/_sidebar-menu.scss create mode 100755 docs/_sass/components/_sidebar.scss create mode 100644 docs/_sass/components/_table.scss create mode 100755 docs/_sass/utils/_mixins.scss create mode 100755 docs/_sass/utils/_variables.scss create mode 100644 docs/_sass/vendors/highlight/dracula.scss create mode 100644 docs/css/docs.scss create mode 100644 docs/docs/README.md rename docs/{ => docs}/db.md (99%) rename docs/{ => docs}/grpc.md (93%) rename docs/{ => docs}/intro.md (99%) rename docs/{ => docs}/middleware.md (98%) rename docs/{ => docs}/registry.md (94%) rename docs/{ => docs}/rpc.md (99%) rename docs/{ => docs}/schema.md (99%) rename docs/{ => docs}/stream.md (96%) rename docs/{ => docs}/transformer.md (98%) create mode 100644 docs/img/favicon.png create mode 100644 docs/img/header-image.svg create mode 100644 docs/img/main-feature-primary.svg create mode 100644 docs/img/main-feature-secondary.svg create mode 100644 docs/img/main-feature-tertiary.svg create mode 100644 docs/img/nav-brand-white.svg create mode 100644 docs/img/nav-brand.svg create mode 100644 docs/img/nav-icon-close.svg create mode 100644 docs/img/nav-icon-open.svg create mode 100644 docs/img/sidebar-icon-open.svg create mode 100644 docs/js/docs.js create mode 100755 docs/js/main.js diff --git a/.gitignore b/.gitignore index a11c47c..312fe41 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,16 @@ stack*.yaml.lock *~ dist *.pyc + +## User files +.DS_Store + +## Jekyll +_site +.sass-cache +.jekyll-metadata +.jekyll-cache + +## Ruby environment normalization: +.bundle/ +/docs/vendor/ diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100755 index 0000000..49bd86a --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "jekyll", ">= 4.0.0" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100755 index 0000000..9904c8c --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,65 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + colorator (1.1.0) + concurrent-ruby (1.1.5) + em-websocket (0.5.1) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0.6.0) + eventmachine (1.2.7) + ffi (1.11.3) + forwardable-extended (2.6.0) + http_parser.rb (0.6.0) + i18n (1.7.0) + concurrent-ruby (~> 1.0) + jekyll (4.0.0) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (>= 0.9.5, < 2) + jekyll-sass-converter (~> 2.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 3.0) + safe_yaml (~> 1.0) + terminal-table (~> 1.8) + jekyll-sass-converter (2.0.1) + sassc (> 2.0.1, < 3.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + kramdown (2.1.0) + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.3) + listen (3.2.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.3.6) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (4.0.1) + rb-fsevent (0.10.3) + rb-inotify (0.10.0) + ffi (~> 1.0) + rouge (3.14.0) + safe_yaml (1.0.5) + sassc (2.2.1) + ffi (~> 1.9) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.6.0) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (>= 4.0.0) + +BUNDLED WITH + 2.0.1 diff --git a/docs/README.md b/docs/README.md index ca109cb..43502a8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,14 +1,29 @@ # Docs for Mu-Haskell -Mu-Haskell is a set of packages that help you build both servers and clients for (micro)services. The main goal of Mu-Haskell is to make you focus on your domain logic, instead of worrying about format and protocol issues. +The documentation is built through a Jekyll site as base. -* [Introduction](intro.md) -* [Schemas](schema.md) - * [Registry](registry.md) -* [Services and servers](rpc.md) - * [gRPC servers and clients](grpc.md) - * [Streams](stream.md) - * [Databases](db.md), including resource pools -* Integration with other libraries - * [Using transformers](transformer.md): look here for logging - * [WAI Middleware](middleware.md): look here for metrics +## Prerequisites + +* You need to have [ruby >= 2.4.0](https://rvm.io/) installed on your system. +* [Bundler >= 2](https://bundler.io/v2.0/guides/bundler_2_upgrade.html) is also needed. + + +## Building the docs + +To preview the site locally, execute the following command from the project root dir. This will install website dependencies under `docs/vendor/bundle`: + +```bash +bundle install --gemfile docs/Gemfile --path vendor/bundle +``` + +Then, through this command, you will run the locally installed Jekyll instance to serve the site: + + +```bash +BUNDLE_GEMFILE=./docs/Gemfile bundle exec jekyll serve -s docs -b /mu-haskell +``` + + +Finally, to have a look at the site, visit: + +http://localhost:4000/mu-haskell diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100755 index 0000000..9ab32fb --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,21 @@ +title: Mu-Haskell +#------------------------- +name: Mu-Haskell +#------------------------- +description: Lorem ipusm +#------------------------- +author: 47 Degrees +keywords: functional-programming, monads, monad-transformers, functional-data-structure, swift, bow, fp-types, adt, free-monads, tagless-final, mtl, for-comprehension, category-theory +#------------------------- +url: https://www.47deg.com +#------------------------- +markdown: kramdown +sass: + sass_dir: _sass + style: compressed + sourcemap: never +#------------------------- +permalink: pretty +#------------------------- +exclude: ['config.ru', 'Gemfile', 'Gemfile.lock', 'vendor', 'Procfile', 'Rakefile'] +#------------------------- diff --git a/docs/_data/menu.yml b/docs/_data/menu.yml new file mode 100755 index 0000000..705db1b --- /dev/null +++ b/docs/_data/menu.yml @@ -0,0 +1,9 @@ +nav: + - title: Documentation + url: / + + - title: Github + url: https://github.com/higherkindness/mu-haskell + + - title: License + url: https://github.com/higherkindness/mu-haskell/blob/master/LICENSE diff --git a/docs/_data/sidebar.yml b/docs/_data/sidebar.yml new file mode 100755 index 0000000..5f68720 --- /dev/null +++ b/docs/_data/sidebar.yml @@ -0,0 +1,32 @@ +options: + - title: Start + url: / + + - title: Introduction + url: intro/ + + - title: Schemas + url: schema/ + nested_options: + - title: Registry + url: registry/ + + - title: Services and servers + url: rpc/ + nested_options: + - title: gRPC + url: grpc/ + + - title: Streams + url: stream/ + + - title: Databases + url: db/ + + - title: Integrations + nested_options: + - title: Transformers + url: transformer/ + + - title: Middleware + url: middleware/ diff --git a/docs/_includes/_doc.html b/docs/_includes/_doc.html new file mode 100644 index 0000000..4cf2abc --- /dev/null +++ b/docs/_includes/_doc.html @@ -0,0 +1,14 @@ +
+
+ +
+
+ {{ content }} +
+
diff --git a/docs/_includes/_footer.html b/docs/_includes/_footer.html new file mode 100755 index 0000000..c627eba --- /dev/null +++ b/docs/_includes/_footer.html @@ -0,0 +1,22 @@ + diff --git a/docs/_includes/_head-docs.html b/docs/_includes/_head-docs.html new file mode 100644 index 0000000..8798d6f --- /dev/null +++ b/docs/_includes/_head-docs.html @@ -0,0 +1,29 @@ + + + {{site.name}} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_includes/_header.html b/docs/_includes/_header.html new file mode 100755 index 0000000..9710685 --- /dev/null +++ b/docs/_includes/_header.html @@ -0,0 +1,13 @@ + diff --git a/docs/_includes/_main.html b/docs/_includes/_main.html new file mode 100755 index 0000000..84a8f11 --- /dev/null +++ b/docs/_includes/_main.html @@ -0,0 +1,13 @@ +
+
+
+ {% for item in site.data.features.content %} +
+ {{ item.title }} +

{{ item.title }}

+

{{ item.description }}

+
+ {% endfor %} +
+
+
\ No newline at end of file diff --git a/docs/_includes/_nav.html b/docs/_includes/_nav.html new file mode 100755 index 0000000..b238cf9 --- /dev/null +++ b/docs/_includes/_nav.html @@ -0,0 +1,32 @@ + diff --git a/docs/_includes/_sidebar.html b/docs/_includes/_sidebar.html new file mode 100755 index 0000000..1603b99 --- /dev/null +++ b/docs/_includes/_sidebar.html @@ -0,0 +1,100 @@ +
+ + +
diff --git a/docs/_layouts/docs.html b/docs/_layouts/docs.html new file mode 100755 index 0000000..e28aed1 --- /dev/null +++ b/docs/_layouts/docs.html @@ -0,0 +1,8 @@ + + + {% include _head-docs.html %} + + {% include _sidebar.html %} + {% include _doc.html %} + + diff --git a/docs/_sass/base/_base.scss b/docs/_sass/base/_base.scss new file mode 100755 index 0000000..7137833 --- /dev/null +++ b/docs/_sass/base/_base.scss @@ -0,0 +1,64 @@ +// Base +// ----------------------------------------------- +// ----------------------------------------------- +// Body, html +// ----------------------------------------------- +html { + box-sizing: border-box; + font-size: $base-font-size; +} + +*, +*::after, +*::before { + box-sizing: inherit; +} + +body, +html { + height: 100%; +} + +// Typography +// ----------------------------------------------- +body { + display: flex; + flex-direction: column; + color: $base-font-color; + background: $white; + font-family: $base-font-family; + line-height: $base-line-height; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + color: $header-font-color; + font-family: $header-font-family; + font-weight: $font-semibold; +} + +a { + color: $link-color; + text-decoration: none; + transition: color $base-duration $base-timing; + + &:visited { + color: $link-color; + } + &:hover { + color: $link-hover; + text-decoration: underline; + } + &:active { + color: $white; + } +} + +hr { + display: block; + border: none; +} diff --git a/docs/_sass/base/_helpers.scss b/docs/_sass/base/_helpers.scss new file mode 100644 index 0000000..30ceca6 --- /dev/null +++ b/docs/_sass/base/_helpers.scss @@ -0,0 +1,10 @@ +// Helpers +// ----------------------------------------------- +// ----------------------------------------------- +.wrapper { + padding: 0 ($base-point-grid * 3); + margin: 0 auto; + box-sizing: border-box; + max-width: $bp-xlarge; + height: 100%; +} diff --git a/docs/_sass/base/_reset.scss b/docs/_sass/base/_reset.scss new file mode 100755 index 0000000..76220f6 --- /dev/null +++ b/docs/_sass/base/_reset.scss @@ -0,0 +1,141 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ +a, +abbr, +acronym, +address, +applet, +article, +aside, +audio, +b, +big, +blockquote, +body, +canvas, +caption, +center, +cite, +code, +dd, +del, +details, +dfn, +div, +dl, +dt, +em, +embed, +fieldset, +figcaption, +figure, +footer, +form, +h1, +h2, +h3, +h4, +h5, +h6, +header, +hgroup, +html, +i, +iframe, +img, +ins, +kbd, +label, +legend, +li, +mark, +menu, +nav, +object, +ol, +output, +p, +pre, +q, +ruby, +s, +samp, +section, +small, +span, +strike, +strong, +sub, +summary, +sup, +table, +tbody, +td, +tfoot, +th, +thead, +time, +tr, +tt, +u, +ul, +var, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} + +body { + line-height: 1; +} + +ol, +ul { + list-style: none; +} + +blockquote, +q { + quotes: none; +} + +blockquote { + &:after, + &:before { + content: ''; + content: none; + } +} + +q { + &:after, + &:before { + content: ''; + content: none; + } +} + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/docs/_sass/components/_button.scss b/docs/_sass/components/_button.scss new file mode 100644 index 0000000..b01a630 --- /dev/null +++ b/docs/_sass/components/_button.scss @@ -0,0 +1,47 @@ +// Buttons +// ---------------------------------------------- +// ---------------------------------------------- +.button { + display: block; + background: none; + border: none; + outline: none; + text-decoration: none; + position: relative; + + &:hover { + cursor: pointer; + } + + > img { + vertical-align: bottom; + } +} + + +.close { + height: 28px; + position: absolute; + left: 0; + top: 0; + width: 32px; + + &::before, + &::after { + background-color: $white; + content: " "; + height: 100%; + left: 98%; + position: absolute; + top: 50%; + width: 2px; + } + + &::before { + transform: rotate(45deg); + } + + &::after { + transform: rotate(-45deg); + } +} diff --git a/docs/_sass/components/_code.scss b/docs/_sass/components/_code.scss new file mode 100755 index 0000000..aa073d3 --- /dev/null +++ b/docs/_sass/components/_code.scss @@ -0,0 +1,23 @@ +// Code +// ---------------------------------------------- +// ---------------------------------------------- +p code, +ul code { + padding: 2px $base-point-grid; + background: rgba($gray-primary, 0.1); + font-family: $code-font-family; + border-radius: 2px; +} + + +.highlight pre { + background: rgba($brand-primary, 0.06); + padding: ($base-point-grid * 3); + overflow: auto; + margin-bottom: ($base-point-grid * 2); +} + + +code { + font-family: $code-font-family; +} diff --git a/docs/_sass/components/_doc.scss b/docs/_sass/components/_doc.scss new file mode 100755 index 0000000..cfbc00c --- /dev/null +++ b/docs/_sass/components/_doc.scss @@ -0,0 +1,97 @@ +// Doc content +// ----------------------------------------------- +// ----------------------------------------------- +#site-doc { + position: absolute; + left: 290px; + right: 0; + top: 0; + bottom: 0; + transition: left $base-duration $base-timing; + + &.expanded { + left: 0; + } + + .doc-header { + display: flex; + align-items: center; + height: ($base-point-grid * 11); + padding: 0 ($base-point-grid * 3)0 0; + background: $white; + + .doc-toggle { + transition: transform $base-duration $base-timing; + + &:hover { + transform: scaleX(1.5); + } + + > * { + padding: ($base-point-grid * 2); + margin: ($base-point-grid * 2); + } + } + } + + .doc-content { + padding: ($base-point-grid * 3); + } + + h1 { + font-size: 2.5rem; + border-bottom: 1px solid $border-color; + } + h2 { + font-size: 2rem; + border-bottom: 1px solid $border-color; + } + h3 { + font-size: 1.5rem; + } + h4 { + font-size: 1.25rem; + } + h5 { + font-size: 1.125rem; + } + h6 { + font-size: 1rem; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: { + top: ($base-point-grid * 3); + bottom: ($base-point-grid * 2); + } + + &:first-child { + margin-top: 0; + } + } + + p { + margin: ($base-point-grid * 2) 0; + } + + ul { + padding-left: 20px; + margin-bottom: ($base-point-grid * 2); + li { + list-style: disc; + } + } +} + +// Responsive +// ----------------------------------------------- +@include bp(medium) { + #site-doc { + left: 0; + } +} diff --git a/docs/_sass/components/_footer.scss b/docs/_sass/components/_footer.scss new file mode 100755 index 0000000..cb77883 --- /dev/null +++ b/docs/_sass/components/_footer.scss @@ -0,0 +1,85 @@ +// Footer +// ----------------------------------------------- +// ----------------------------------------------- +#site-footer { + flex: 0 0 0; + height: 200px; + padding: ($base-point-grid * 10) 0; + background: $brand-primary; + color: rgba($white, 0.5); + + a { + color: rgba($white, 0.8); + + &:visited { + color: rgba($white, 0.8); + } + + &:hover { + color: rgba($white, 0.6); + text-decoration: underline; + } + + &:active { + color: rgba($white, 0.8); + } + + + } + + .footer-flex { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + + .footer-dev { + width: $column-4; + } + + .footer-menu { + display: flex; + + li { + &:not(:last-child) { + margin-right: ($base-point-grid * 4) + } + } + } + } +} + +// Responsive +// ----------------------------------------------- + +@include bp(medium) { + #site-footer { + .footer-flex { + justify-content: center; + flex-wrap: wrap; + + .footer-dev, + .footer-menu { + width: $column-8; + } + + .footer-dev { + padding-bottom: ($base-point-grid * 2); + margin-bottom: ($base-point-grid * 2); + text-align: center; + border-bottom: 1px solid rgba($white, 0.2); + } + + + .footer-menu { + justify-content: center; + + li { + &:not(:last-child) { + margin-right: ($base-point-grid * 2); + } + } + } + } + } +} diff --git a/docs/_sass/components/_header.scss b/docs/_sass/components/_header.scss new file mode 100755 index 0000000..4167c04 --- /dev/null +++ b/docs/_sass/components/_header.scss @@ -0,0 +1,109 @@ +// Header +// ----------------------------------------------- +// ----------------------------------------------- + +#site-header { + flex: 1 0 auto; + margin-top: ($base-point-grid * 18); + background: rgba($brand-primary, 0.06); + + .header-flex { + display: flex; + align-items: center; + justify-content: space-evenly; + color: $white; + height: 100%; + + .header-text { + width: $column-5; + + h1 { + color: $base-font-color; + font-size: 4.188rem; + line-height: 1.3; + + span { + display: block; + margin: ($base-point-grid * 3) 0; + font-size: 1.286rem; + font-weight: $font-regular; + + strong { + font-weight: $font-bold; + } + } + } + + .header-button { + padding: ($base-point-grid * 1.5) ($base-point-grid * 6); + display: inline-block; + font-weight: $font-semibold; + text-transform: uppercase; + color: $white; + border: none; + background: $brand-primary; + border-radius: 300px; + transition: color $base-duration $base-timing, background-color $base-duration $base-timing; + + &:visited { + color: $white; + } + + &:hover { + text-decoration: none; + color: $white; + background: darken($brand-primary, 0.2); + } + + &:active { + color: $white; + background: darken($brand-primary, 0.2); + + } + } + } + + .header-image { + width: 33%; + text-align: center; + } + } +} + +// Responsive +// ----------------------------------------------- + +@include bp(large) { + #site-header { + .header-flex { + .header-text { + h1 { + font-size: 2.9rem; + } + } + .header-image { + img { + width: 100%; + } + } + } + } +} +@include bp(medium) { + #site-header { + .header-flex { + padding: ($base-point-grid * 20) 0; + .header-text { + text-align: center; + width: $column-12; + + h1 { + font-size: 2.5rem; + } + } + .header-image { + display: none; + } + } + } +} diff --git a/docs/_sass/components/_main.scss b/docs/_sass/components/_main.scss new file mode 100755 index 0000000..245455a --- /dev/null +++ b/docs/_sass/components/_main.scss @@ -0,0 +1,51 @@ +// Features +// ----------------------------------------------- +// ----------------------------------------------- + +#site-main { + flex: 1 0 auto; + padding: ($base-point-grid * 10) 0; + + .main-flex { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + + .main-item { + width: $column-4; + text-align: center; + + &:not(:last-child) { + margin-right: $gutter-margin; + } + + img { + margin-bottom: $base-point-grid; + } + + h2 { + margin-bottom: $base-point-grid; + font-size: 1.429rem; + } + } + } +} + +// Responsive +// ----------------------------------------------- +@include bp(medium) { + #site-main { + .main-flex { + flex-direction: column; + .main-item { + width: $column-12; + + &:not(:last-child) { + margin-right: 0; + margin-bottom: ($base-point-grid * 8); + } + } + } + } +} diff --git a/docs/_sass/components/_nav.scss b/docs/_sass/components/_nav.scss new file mode 100755 index 0000000..61e4051 --- /dev/null +++ b/docs/_sass/components/_nav.scss @@ -0,0 +1,141 @@ +// Nav +// ----------------------------------------------- +// ----------------------------------------------- +#site-nav { + flex: 0 0 auto; + position: fixed; + padding: ($base-point-grid * 5) 0; + width: 100%; + transition: background-color $base-duration $base-timing, padding $base-duration $base-timing; + height: ($base-point-grid * 18); + + &.nav-scroll { + padding: ($base-point-grid * 2) 0; + background: rgba(244, 245, 255, 0.9); + + } + + .nav-flex { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + + .nav-brand { + display: flex; + align-items: center; + font-family: $base-font-family; + font-size: 1.5rem; + color: $base-font-color; + + &:visited, + &:hover, + &:active { + color: $base-font-color; + text-decoration: none; + } + } + + .nav-menu { + position: relative; + + ul { + display: flex; + + .nav-menu-item { + &:not(:last-child) { + margin-right: ($base-point-grid * 5); + } + + a { + padding-bottom: 4px; + font-family: $base-font-family; + color: $gray-primary; + + &:hover { + text-decoration: none; + border-bottom: 2px solid $brand-primary; + } + } + } + } + } + + .nav-icon-open { + padding: 16px; + margin: -16px; + display: none; + transition: transform $base-duration $base-timing; + + &:hover { + transform: scaleX(1.5); + } + } + + .nav-icon-close { + display: none; + padding: 6px; + position: absolute; + background: rgba($brand-primary, 0.96); + right: 100%; + top: 32px; + + img { + display: block; + transition: transform .3s ease; + + &:hover { + transform: rotate(180deg); + } + } + } + } +} + +// Responsive +// ----------------------------------------------- +@include bp(medium) { + #site-nav { + .nav-flex { + .nav-menu { + position: fixed; + padding: ($base-point-grid * 4) ($base-point-grid * 6); + background: rgba($brand-primary, 0.96); + height: 100%; + right: -100%; + top: 0; + width: 50%; + z-index: 2; + transition: right $base-duration $base-timing; + + &.open { + right: 0; + } + + ul { + flex-direction: column; + + .nav-menu-item { + padding: $base-point-grid 0; + &:not(:last-child) { + margin-right: 0; + } + + a { + color: $white; + &:hover { + border-bottom-color: $white; + } + } + } + } + + } + + .nav-icon-open, + .nav-icon-close { + display: block; + } + } + } +} diff --git a/docs/_sass/components/_sidebar-menu.scss b/docs/_sass/components/_sidebar-menu.scss new file mode 100644 index 0000000..439c943 --- /dev/null +++ b/docs/_sass/components/_sidebar-menu.scss @@ -0,0 +1,115 @@ +// Sidebar menu +// ----------------------------------------------- +// ----------------------------------------------- + +.sidebar-menu { + margin-top: ($base-point-grid * 2); + padding: 0; + + .sidebar-menu-item { + display: flex; + flex-direction: column; + position: relative; + + .sub-menu { + background: $sidebar-active-color; + max-height: 0; + transition: max-height 0.3s ease-in-out; + overflow: hidden; + + a { + display: flex; + justify-content: flex-start; + align-items: center; + padding: $base-point-grid * 2 $base-point-grid * 4; + font-size: 0.875rem; + height: auto; + + &.active { + color: $white; + box-shadow: 3px 0 $white inset; + } + } + } + + a, button { + box-sizing: border-box; + font-family: $base-font-family; + font-size: 1rem; + display: flex; + justify-content: space-between; + align-items: center; + padding: $base-point-grid * 2; + line-height: $base-point-grid * 2; + width: 100%; + color: $white; + @include links($white, $white, rgba($white, 0.8), $white); + transition: background $base-duration $base-timing; + + &:hover { + text-decoration: none; + } + } + + .caret { + position: absolute; + right: ($base-point-grid * 3); + top: $base-point-grid * 2; + pointer-events: none; + } + + .caret::before { + content: ''; + position: absolute; + top: 0; + left: 0; + border-left: 6px solid rgba($white, 0.8); + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + transition: border 0.3s ease, top 0.2s ease, left 0.2s ease; + } + + .caret::after { + content: ''; + position: absolute; + left: 0; + top: 2px; + border-left: 4px solid $brand-primary; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + transition: border 0.3s ease, top 0.3s ease, left 0.3s ease; + } + + &.active { + > a, button { + box-shadow: 3px 0 $white inset; + } + } + + &.open { + > a, button { + background: $sidebar-head-active-color; + } + + .caret::before { + top: 4px; + left: -6px; + border-top: 6px solid rgba($white, 0.8); + border-left: 6px solid transparent; + border-right: 6px solid transparent; + } + + .caret::after { + left: -4px; + top: 4px; + border-top: 4px solid $brand-primary; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + } + + .sub-menu { + max-height: 1600px; // This will suffice for +20 entries in a submenu tops + } + } + } +} diff --git a/docs/_sass/components/_sidebar.scss b/docs/_sass/components/_sidebar.scss new file mode 100755 index 0000000..4d9699f --- /dev/null +++ b/docs/_sass/components/_sidebar.scss @@ -0,0 +1,89 @@ +// Sidebar +// ----------------------------------------------- +// ----------------------------------------------- + +#site-sidebar { + position: fixed; + background-image: linear-gradient(to bottom, $brand-primary 60%, darken($brand-primary, 6%) 100%); + width: 290px; + height: 100%; + left: 0; + z-index: 2; + transition: left $base-duration $base-timing; + + &:hover { + overflow: hidden auto; + } + + &.toggled { + left: -100%; + } + + .sidebar-brand { + padding: $base-point-grid + 4 $base-point-grid * 2; + font-family: $header-font-family; + font-size: 18px; + display: flex; + justify-content: center; + align-items: center; + background-color: $sidebar-active-color; + + a { + display: flex; + color: $white; + justify-content: center; + align-items: center; + width: 100%; + + &:visited, + &:hover, + &:active { + text-decoration: none; + } + + .brand-wrapper { + width: auto; + height: 64px; + } + + span { + font-size: 1.5rem; + z-index: 30; + white-space: nowrap; + font-weight: 500; + } + } + } + + .sidebar-toggle { + display: none; + } +} + +// Responsive +// ----------------------------------------------- +@include bp(medium) { + + #site-sidebar { + left: -100%; + width: 100%; + + &.toggled { + left: 0; + } + + .sidebar-toggle { + position: absolute; + right: 16px;; + padding: 24px 32px; + display: block; + opacity: 0.7; + transition: opacity 0.3s ease, transform 0.3s ease; + + &:hover { + opacity: 1; + transform: rotate(-180deg); + } + } + } +} diff --git a/docs/_sass/components/_table.scss b/docs/_sass/components/_table.scss new file mode 100644 index 0000000..1909993 --- /dev/null +++ b/docs/_sass/components/_table.scss @@ -0,0 +1,29 @@ +table { + font-size: 1rem; + text-align: left; + overflow-x: auto; + + th { + border-bottom: 3px solid rgba($brand-primary, 0.3); + border-radius: 0; + font-weight: $font-semibold; + } + + tr { + border-bottom: 1px solid rgba($brand-primary, 0.3); + border-radius: 0; + } + + th, + td { + padding: $base-point-grid $base-point-grid * 4; + + &:first-of-type { + padding-left: $base-point-grid * 2; + } + + &:last-of-type { + padding-right: $base-point-grid * 2; + } + } +} diff --git a/docs/_sass/utils/_mixins.scss b/docs/_sass/utils/_mixins.scss new file mode 100755 index 0000000..59419d4 --- /dev/null +++ b/docs/_sass/utils/_mixins.scss @@ -0,0 +1,53 @@ +// Mixins +// ----------------------------------------------- +// ----------------------------------------------- + +// Hover +//------------------------------------------------ +@mixin links($link, $visited, $hover, $active) { + & { + color: $link; + + &:visited { + color: $visited; + } + + &:hover { + color: $hover; + } + + &:active, + &:focus { + color: $active; + } + } +} + +// Breakpoint +// ----------------------------------------------- +// ----------------------------------------------- +@mixin bp($point) { + @if $point==xlarge { + @media (max-width: $bp-xlarge) { + @content; + } + } + + @if $point==large { + @media (max-width: $bp-large) { + @content; + } + } + + @if $point==medium { + @media (max-width: $bp-medium) { + @content; + } + } + + @if $point==small { + @media (max-width: $bp-small) { + @content; + } + } +} diff --git a/docs/_sass/utils/_variables.scss b/docs/_sass/utils/_variables.scss new file mode 100755 index 0000000..d10fb99 --- /dev/null +++ b/docs/_sass/utils/_variables.scss @@ -0,0 +1,74 @@ +// Variables +// ----------------------------------------------- +// ----------------------------------------------- + +// ----------------------------------------------- +// Typography +// ----------------------------------------------- +@import url('https://fonts.googleapis.com/css?family=Fira+Mono:400,500,700&display=swap'); +@import url('https://fonts.googleapis.com/css?family=Montserrat:400,600,700&display=swap'); +// @import url('https://fonts.googleapis.com/css?family=Hind:400,500,600&display=swap'); + +// Colors +// ----------------------------------------------- +$brand-primary: #66296a; +$brand-secondary: #001f39; +$gray-primary: #001f39; +$white: rgb(255, 255, 255); +$link-color: darken($brand-primary, 10%); +$link-hover: darken($brand-primary, 15%); +$sidebar-active-color: lighten($brand-primary, 2%); +$sidebar-head-active-color: lighten($brand-primary, 4%); + +// Typography +// ----------------------------------------------- +$base-font-family: 'Montserrat', sans-serif; +// $header-font-family: 'Hind', sans-serif; +$header-font-family: $base-font-family; +$code-font-family: 'Fira Mono', monospace; +//- +$base-font-color: $gray-primary; +$header-font-color: $base-font-color; +//- +$font-regular: 400; +$font-semibold: 600; +$font-bold: 700; +//- +$base-font-size: 15px; +$base-line-height: 1.6; + +// Sizes +// ----------------------------------------------- +$base-point-grid: 8px; +// Animation +// ----------------------------------------------- +$base-duration: 250ms; +$base-timing: ease-in-out; + +// Breakpoint +// ----------------------------------------------- +$bp-small: 480px; +$bp-medium: 768px; +$bp-large: 992px; +$bp-xlarge: 1140px; + +// Grid +// ----------------------------------------------- +$column-1: (1/12*100%); +$column-2: (2/12*100%); +$column-3: (3/12*100%); +$column-4: (4/12*100%); +$column-5: (5/12*100%); +$column-6: (6/12*100%); +$column-7: (7/12*100%); +$column-8: (8/12*100%); +$column-9: (9/12*100%); +$column-10: (10/12*100%); +$column-11: (11/12*100%); +$column-12: (12/12*100%); +$gutter-margin: ($base-point-grid * 4); + + +// Border +// ----------------------------------------------- +$border-color: rgba($gray-primary, 0.1); diff --git a/docs/_sass/vendors/highlight/dracula.scss b/docs/_sass/vendors/highlight/dracula.scss new file mode 100644 index 0000000..8416140 --- /dev/null +++ b/docs/_sass/vendors/highlight/dracula.scss @@ -0,0 +1,167 @@ +/* Dracula Theme v1.2.5 + * + * https://github.com/zenorocha/dracula-theme + * + * Copyright 2016, All rights reserved + * + * Code licensed under the MIT license + * http://zenorocha.mit-license.org + * + * @author Rob G + * @author Chris Bracco + * @author Zeno Rocha + * @author Piruin Panichphol + */ + +/* + * Variables + */ + +$dt-gray-dark: #282a36; // Background +$dt-gray: #44475a; // Current Line & Selection +$dt-gray-light: #f8f8f2; // Foreground +$dt-blue: #6272a4; // Comment +$dt-cyan: #8be9fd; +$dt-green: #50fa7b; +$dt-orange: #ffb86c; +$dt-pink: #ff79c6; +$dt-purple: #bd93f9; +$dt-red: #ff5555; +$dt-yellow: #f1fa8c; + +/* + * Styles + */ + +.highlight { + background: $dt-gray-dark; + color: $dt-gray-light; + + .hll, + .s, + .sa, + .sb, + .sc, + .dl, + .sd, + .s2, + .se, + .sh, + .si, + .sx, + .sr, + .s1, + .ss { + color: $dt-yellow; + } + + .go { + color: $dt-gray; + } + + .err, + .g, + .l, + .n, + .x, + .p, + .ge, + .gr, + .gh, + .gi, + .gp, + .gs, + .gu, + .gt, + .ld, + .no, + .nd, + .ni, + .ne, + .nn, + .nx, + .py, + .w, + .bp { + color: $dt-gray-light; + } + + .gh, + .gi, + .gu { + font-weight: bold; + } + + .ge { + text-decoration: underline; + } + + .bp { + font-style: italic; + } + + .c, + .ch, + .cm, + .cpf, + .c1, + .cs { + color: $dt-blue; + } + + .kd, + .kt, + .nb, + .nl, + .nv, + .vc, + .vg, + .vi, + .vm { + color: $dt-cyan; + } + + .kd, + .nb, + .nl, + .nv, + .vc, + .vg, + .vi, + .vm { + font-style: italic; + } + + .na, + .nc, + .nf, + .fm { + color: $dt-green; + } + + .k, + .o, + .cp, + .kc, + .kn, + .kp, + .kr, + .nt, + .ow { + color: $dt-pink; + } + + .m, + .mb, + .mf, + .mh, + .mi, + .mo, + .il { + color: $dt-purple; + } + + .gd { + color: $dt-red; + } +} diff --git a/docs/css/docs.scss b/docs/css/docs.scss new file mode 100644 index 0000000..0ba96a3 --- /dev/null +++ b/docs/css/docs.scss @@ -0,0 +1,23 @@ +--- +--- + +// Utils +@import "utils/variables"; +@import "utils/mixins"; + +// Base +@import "base/reset"; +@import "base/base"; +@import "base/helpers"; + +// Components +@import "components/button"; +@import "components/footer"; +@import "components/sidebar"; +@import "components/sidebar-menu"; +@import "components/doc"; +@import "components/code"; +@import "components/table"; + +// Vendor +@import "vendors/highlight/dracula"; diff --git a/docs/docs/README.md b/docs/docs/README.md new file mode 100644 index 0000000..575a09c --- /dev/null +++ b/docs/docs/README.md @@ -0,0 +1,20 @@ +--- +layout: docs +title: Mu-Haskell +permalink: / +--- + +# Docs for Mu-Haskell + +Mu-Haskell is a set of packages that help you build both servers and clients for (micro)services. The main goal of Mu-Haskell is to make you focus on your domain logic, instead of worrying about format and protocol issues. + +* [Introduction]({% link docs/intro.md %}) +* [Schemas]({% link docs/schema.md %}) + * [Registry]({% link docs/registry.md %}) +* [Services and servers]({% link docs/rpc.md %}) + * [gRPC servers and clients]({% link docs/grpc.md %}) + * [Streams]({% link docs/stream.md %}) + * [Databases]({% link docs/db.md %}), including resource pools +* Integration with other libraries + * [Using transformers]({% link docs/transformer.md %}): look here for logging + * [WAI Middleware]({% link docs/middleware.md %}): look here for metrics diff --git a/docs/db.md b/docs/docs/db.md similarity index 99% rename from docs/db.md rename to docs/docs/db.md index 9b8a649..5706752 100644 --- a/docs/db.md +++ b/docs/docs/db.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: db/ +--- + # Databases In this section of the docs, to have a clearer understanding of how one would use `mu-haskell` to talk to a database, we are going to have a walk through the example of [`with-persistent`](https://github.com/higherkindness/mu-haskell/tree/master/examples/with-persistent). diff --git a/docs/grpc.md b/docs/docs/grpc.md similarity index 93% rename from docs/grpc.md rename to docs/docs/grpc.md index 6863378..1d9b318 100644 --- a/docs/grpc.md +++ b/docs/docs/grpc.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: grpc/ +--- + # gRPC servers and clients Mu-Haskell defines a generic notion of service and server that implements it. This generic server can then be used by `mu-grpc-server`, to provide a concrete implementation using a specific wire format. Or you can use `mu-grpc-client` to build a client. diff --git a/docs/intro.md b/docs/docs/intro.md similarity index 99% rename from docs/intro.md rename to docs/docs/intro.md index f4366ee..8ba37cd 100644 --- a/docs/intro.md +++ b/docs/docs/intro.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: intro/ +--- + # Introduction to Mu-Haskell Many companies have embraced microservices architectures as the best way to scale up their internal software systems, separate work across different company divisions and development teams. Microservices architectures also allow teams to turn an idea or bug report into a working feature of fix in production more quickly, in accordance to the agile principles. diff --git a/docs/middleware.md b/docs/docs/middleware.md similarity index 98% rename from docs/middleware.md rename to docs/docs/middleware.md index 7f49211..5337014 100644 --- a/docs/middleware.md +++ b/docs/docs/middleware.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: middleware/ +--- + # Integration with WAI middleware Although you usually run a `mu-rpc` server directly using a function like `runGRpcApp`, this is just a convenience function to make it simpler to run the server. Under the hood, the library generates a so-called WAI application, which is then fed to an actual server. diff --git a/docs/registry.md b/docs/docs/registry.md similarity index 94% rename from docs/registry.md rename to docs/docs/registry.md index 72403d5..27c8026 100644 --- a/docs/registry.md +++ b/docs/docs/registry.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: registry/ +--- + # Registry Schemas evolve over time. It is a good practice to keep an inventory of all the schemas you can work with, in the form of a *registry*. Using `mu-schema` you can declare one such registry as simply a mapping from versions to schemas: diff --git a/docs/rpc.md b/docs/docs/rpc.md similarity index 99% rename from docs/rpc.md rename to docs/docs/rpc.md index 99aa35f..79b4d40 100644 --- a/docs/rpc.md +++ b/docs/docs/rpc.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: rpc/ +--- + # Services and servers There are several formats in the wild used to declare service APIs, including [Avro IDL](https://avro.apache.org/docs/current/idl.html), [gRPC](https://grpc.io/), and [OpenAPI](https://swagger.io/specification/). `mu-rpc` abstract the commonalities into a single type-level format for declaring these services, building on the format-independent schema facilities of `mu-schema`. In addition, this package provides a generic notion of *server* of a service. One such server defines one behavior for each method in the service, but does not bother with (de)serialization mechanisms. diff --git a/docs/schema.md b/docs/docs/schema.md similarity index 99% rename from docs/schema.md rename to docs/docs/schema.md index 0c1be93..ddb2ec2 100644 --- a/docs/schema.md +++ b/docs/docs/schema.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: schema/ +--- + # Schemas Using `mu-schema` you can describe a schema for your data using type-level techniques. You can then automatically generate: diff --git a/docs/stream.md b/docs/docs/stream.md similarity index 96% rename from docs/stream.md rename to docs/docs/stream.md index 8ce6190..30779e7 100644 --- a/docs/stream.md +++ b/docs/docs/stream.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: stream/ +--- + # Streams In the docs about [service definition](rpc.md) we had one single `SayHello` method which takes one value and produces one value. However, we can also declare methods which perform streaming, such as: diff --git a/docs/transformer.md b/docs/docs/transformer.md similarity index 98% rename from docs/transformer.md rename to docs/docs/transformer.md index 1ec4989..a17e6d2 100644 --- a/docs/transformer.md +++ b/docs/docs/transformer.md @@ -1,3 +1,9 @@ +--- +layout: docs +title: Mu-Haskell +permalink: transformer/ +--- + # Integration using transformers You might be wondering: how can I integrate my favorite logging library with `mu-grpc-server`? Our [explanation of services](rpc.md) introduced `MonadServer` as the simplest set of capabilities required for a server: diff --git a/docs/img/favicon.png b/docs/img/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..74aa4b9f301875711ce055a38b45b94e4f28009b GIT binary patch literal 2790 zcmVo7lfl5@O62lnUzlLMg)N`irOyIr17TdR`2$puV>FHNA zpxUWE!GTu+wS&C9&1mT}1)3jjSMMtd(8M|)QKk4Q(D^`McuLZ0Vm1kmu-piol8p9O zSTpmj`u;%=XhNgY)jfR1crkD&P!PVpst_!^r(J&;_}Q9zpDMf>ct_H7Pi!@Hx9Q=7 z63}25j5H(PqF)XL&;u4w?b&|2LpK8-8qoYFN#}I7=Nn-|nVIJII`S%sOw#nTAkd7B>y$rW0OfKH zH>YU?UkSVxh`?(?2Mase^z@V|9?^4{@9a;)&;4It!1^iR7 z#ka){=4@)!U_h zQYmI5&jm&U+mV+&R~=mYz#2UV)~PuT*_&LYVUW|C!OH|6Pn!NuXm)3-zER2{X~kCy zowqBD%%i+VvA<~eKyvI)gFsE?%BFUz-{>&D7Hev9ZGS*+!}=637I+wRe!f-r?Q=lc zoX13|_%fuKz(}A6X-Sx-xnr$%jL*4hY>FAk3xGp*mD3<{?AHBeACC&zi-I2V$ zuXd`x+AkYx;piTpS5xP?U2Uuf`NaV#rat-w=nTOze;mQ_ig_JCO7sk?#3r5V*QcU* zDOLj@nJ0|q<=bchdBC*(ndBxsW3(vsBwy<2P~Tv3ly!CWHk$9cOV5`no9;MP(@_yW z+Z=M5#p~jj&P})KvC=Uoo$a@Tp??lk59sQr;gg!!(V@N}2Q)tCs>4#umOMW>=?=*& zMh3w(ci*DFWwTE8jiXWWmB4F&KFMp+VX$z+&H8h)TR%tmnnaE<_AP|L{QNrou^idd z{F+ZH@Dj|CKny&d%zgm9k{UZ(^tFMTU;-~Tyji&0gm@ltQI5d9pr$>UQTnBQzF!q=j~5`#07d|h8s8^W2W;<^ z#+93dhb#w0>3A{LM4*RQQ}gR}XDN>a_Hx@F8!V6Pl%ofg@Z$FDitif`xgCeX!ZgAAJFN@^K0v)_ZdzA3L~m`bf}guWdpJ}3LrG=0ixdc zdZg(|9{Cz!Fuya&Bbf%D8TERZ#L+L5WANLdT$J_|f)%N>&jKbGO#qBEubA)lF`!bu z+WFO|{tZCV#htCe7XfOf`Q3`V3Ok#C`ME1w)Dbg|fDQQ; zbr0n^UdlQs4d7mGOBQ?c9Q!In2yBsc#SwjcrM*qjaBhe@+SLQxI9&awUTOznHHBms z{U1Omye6m$=60;rHV%SF4Pjp)KokdyI}Z{#B;UvlZHFn$K@&1yB-UT>NiF9Qc+Z zDb0y`{i{ra&wQl=>H{c5d<3AYC7h3y6+8$WjoqH9k2`9n`Q5{L0TUXX&eZ#i+B#pD zt@GPnPC$mD=Q(+~0l@Z+nfhpDcDi4kZ_~yj3Odo~LSPGUvSL3_(-7T|$@%c19{dN- zadmZ%H-W!t`G!b-C{yPPULHW=spNo<1H>bPPh0+Su}L$dUO!S(??!;GR;>xEbS$_T zh-FrV2%eRKJ;y~{Nz6ZP-ymEApADZ0YDMK@SPbmJ;W%<_d zJm7v{)Q*rLlUmshvzmGzCY%Sx1Ciygs5iKxWM|7X_)P3&P_(=V+JjhgN)EKi4W1%< zrRX30_u@day4UH~dphVTQ#_()EHkjL0LBO&H2xvzVj$`(XxzQ++PY5xL1M#8$BRM# zNzvW04RqymWB9@YYgCw&^Qd&1ON{4H^e}EWUNJf>nx-Z+Iz76F&w>{gpC}68FN9UW zmF1cpGW9+Kyc~FI(zKPLNjyo3y0oiJEBkNk**;cbyujAcfxIai8C;z>)P^2VDJDg0js(>Rg8wPqFvkiVjWIvSLj8b&xk5z5Cl|e7bNWMGS3})O6 zq!}Aq^b;6hxDwf9Fb~>l%C~7_=^T@C9-AsYwHHxzqih9zE_{+3c4y_y)OjKDV$8Q4 zs#&qu0&fbelQy>L-eCt+T8I2&+4MW{uK~s}i1l~Z{Drwa3^hNBIgMfg-Pq!~%Qy5D zg3pzkUuqhnTV`@73_8cD{MQ$D-#|U_WV#(B>jgIMR)ie7PQ2$-qjcodD!=hvxe$3MB zt`^;qo#wYjk#8&=3p@(CG~cRkm2>V>&h=}a?~50!xKK?2TaE7!ss~2NJOMhlvrRu3 z)+All6E&D@1{lu=sV92?IKK3BAzd|QE303uG~oqLOxCIBC@y+2IZn!XRC**wcD{wj z_q1$tSSt<(k=Nu>3`CsE=rO^1jk>kq>sDCCJ zWZI9>%0RB$wK%1Fz3wjyeo>Aq5U1~r9QP|g1C|B5PWu2)+q!tS%u}Xr(8K6Ab|SUPot}Q z;yFfhDb|cVC%i1E3YK=P)s9`Z7w;EdJ)oBLCxJDi+{NAj324A3`0t80oiW70<7jn3VIV3WZ8k;-HWJ2PO$@DhJ{}QUCw|07*qoM6N<$f;e + + + header-image + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/img/main-feature-primary.svg b/docs/img/main-feature-primary.svg new file mode 100644 index 0000000..8f7a756 --- /dev/null +++ b/docs/img/main-feature-primary.svg @@ -0,0 +1,75 @@ + + + + feature-primary + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/img/main-feature-secondary.svg b/docs/img/main-feature-secondary.svg new file mode 100644 index 0000000..f73063d --- /dev/null +++ b/docs/img/main-feature-secondary.svg @@ -0,0 +1,110 @@ + + + + main-feature-secondary + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/img/main-feature-tertiary.svg b/docs/img/main-feature-tertiary.svg new file mode 100644 index 0000000..176fbd4 --- /dev/null +++ b/docs/img/main-feature-tertiary.svg @@ -0,0 +1,55 @@ + + + + main-feature-tertiary + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/img/nav-brand-white.svg b/docs/img/nav-brand-white.svg new file mode 100644 index 0000000..99bbd85 --- /dev/null +++ b/docs/img/nav-brand-white.svg @@ -0,0 +1,9 @@ + + + + nav-brand + Created with Sketch. + + + + diff --git a/docs/img/nav-brand.svg b/docs/img/nav-brand.svg new file mode 100644 index 0000000..4230051 --- /dev/null +++ b/docs/img/nav-brand.svg @@ -0,0 +1,9 @@ + + + + nav-brand + Created with Sketch. + + + + \ No newline at end of file diff --git a/docs/img/nav-icon-close.svg b/docs/img/nav-icon-close.svg new file mode 100644 index 0000000..076619e --- /dev/null +++ b/docs/img/nav-icon-close.svg @@ -0,0 +1,12 @@ + + + + nav-icon-close + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/docs/img/nav-icon-open.svg b/docs/img/nav-icon-open.svg new file mode 100644 index 0000000..c4cd84d --- /dev/null +++ b/docs/img/nav-icon-open.svg @@ -0,0 +1,13 @@ + + + + nav-icon-open + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/docs/img/sidebar-icon-open.svg b/docs/img/sidebar-icon-open.svg new file mode 100644 index 0000000..3df658e --- /dev/null +++ b/docs/img/sidebar-icon-open.svg @@ -0,0 +1,11 @@ + + + + sidebar-icon-open + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/docs/js/docs.js b/docs/js/docs.js new file mode 100644 index 0000000..5a87994 --- /dev/null +++ b/docs/js/docs.js @@ -0,0 +1,162 @@ +/** + * Toggle an specific class to the received DOM element. + * @param {string} elemSelector The query selector specifying the target element. + * @param {string} [activeClass='active'] The class to be applied/removed. + */ +function toggleClass(elemSelector, activeClass = 'active') { + const elem = document.querySelector(elemSelector); + if (elem) { + elem.classList.toggle(activeClass); + } +} + +/** + * Toggle specific classes to an array of corresponding DOM elements. + * @param {Array} elemSelectors The query selectors specifying the target elements. + * @param {Array} activeClasses The classes to be applied/removed. + */ +function toggleClasses(elemSelectors, activeClasses) { + elemSelectors.map((elemSelector, idx) => { + toggleClass(elemSelector, activeClasses[idx]); + }); +} + +/** + * Remove active class from siblings DOM elements and apply it to event target. + * @param {Element} element The element receiving the class, and whose siblings will lose it. + * @param {string} [activeClass='active'] The class to be applied. + */ +function activate(element, activeClass = 'active') { + [...element.parentNode.children].map((elem) => elem.classList.remove(activeClass)); + element.classList.add(activeClass); +} + +/** + * Remove active class from siblings parent DOM elements and apply it to element target parent. + * @param {Element} element The element receiving the class, and whose siblings will lose it. + * @param {string} [activeClass='active'] The class to be applied. + */ +function activateParent(element, activeClass = 'active') { + const elemParent = element.parentNode; + activate(elemParent, activeClass); +} + +/** + * Remove active class from siblings parent DOM elements and apply it to element target parent. + * @param {Element} element The element receiving the class, and whose siblings will lose it. + * @param {string} [activeClass='active'] The class to be applied. + */ +function toggleParent(element, activeClass = "active") { + const elemParent = element.parentNode; + if (elemParent) { + elemParent.classList.toggle(activeClass); + } +} + +/** + * This will make the specified elements click event to show/hide the menu sidebar. + */ +function activateToggle() { + const menuToggles = document.querySelectorAll("#menu-toggle, #main-toggle"); + if (menuToggles) { + [...menuToggles].map(elem => { + elem.onclick = e => { + e.preventDefault(); + toggleClass("#site-sidebar", "toggled"); + toggleClass("#site-doc", "expanded"); + }; + }); + } +} + +/** + * This will make the specified elements click event to behave as a menu + * parent entry, or a link, or sometimes both, depending on the context. + */ +function activateMenuNesting() { + const menuParents = document.querySelectorAll(".drop-nested"); + if (menuParents) { + [...menuParents].map(elem => { + elem.onclick = e => { + e.preventDefault(); + toggleParent(elem, "open"); + const elementType = e.currentTarget.tagName.toLowerCase(); + if (elementType === "a") { + const linkElement = e.currentTarget; + const linkElementParent = linkElement.parentNode; + const destination = linkElement.href; + if ( + destination !== window.location.href && + !linkElementParent.classList.contains("active") + ) { + window.location.href = destination; + } + } + }; + }); + } +} + +/** + * Aux function to retrieve repository stars and watchers count info from + * GitHub API and set it on its proper nodes. + */ +async function loadGitHubStats() { + const content = document.querySelector("#content"); + const ghOwner = content.dataset.githubOwner; + const ghRepo = content.dataset.githubRepo; + + if (ghOwner && ghRepo) { + const ghAPI = `https://api.github.com/repos/${ghOwner}/${ghRepo}`; + const ghDataResponse = await fetch(ghAPI); + const ghData = await ghDataResponse.json(); + const watchersElement = document.querySelector("#eyes"); + const starsElement = document.querySelector("#stars"); + watchersElement.textContent = ghData.subscribers_count; + starsElement.textContent = ghData.stargazers_count; + } +} + +/** + * Function to create an anchor with an specific id + * @param {string} id The corresponding id from which the href will be created. + * @returns {Element} The new created anchor. + */ +function anchorForId(id) { + const anchor = document.createElement("a"); + anchor.className = "header-link"; + anchor.href = `#${id}`; + anchor.innerHTML = ''; + return anchor; +} + +/** + * Aux function to retrieve repository stars and watchers count info from + * @param {string} level The specific level to select header from. + * @param {Element} containingElement The element receiving the anchor. + */ +function linkifyAnchors(level, containingElement) { + const headers = containingElement.getElementsByTagName(`h${level}`); + [...headers].map(header => { + if (typeof header.id !== "undefined" && header.id !== "") { + header.append(anchorForId(header.id)); + } + }); +} + +/** + * Function + */ +function linkifyAllLevels() { + const content = document.querySelector("#content"); + [...Array(7).keys()].map(level => { + linkifyAnchors(level, content); + }); +} + +window.addEventListener("DOMContentLoaded", () => { + activateToggle(); + activateMenuNesting(); + // loadGitHubStats(); + // linkifyAllLevels(); +}); diff --git a/docs/js/main.js b/docs/js/main.js new file mode 100755 index 0000000..b5496ee --- /dev/null +++ b/docs/js/main.js @@ -0,0 +1,31 @@ +// This initialization requires that this script is loaded with `defer` +const navElement = document.querySelector("#site-nav"); + +/** + * Toggle an specific class to the received DOM element. + * @param {string} elemSelector The query selector specifying the target element. + * @param {string} [activeClass='active'] The class to be applied/removed. + */ +function toggleClass(elemSelector, activeClass = "active") { + const elem = document.querySelector(elemSelector); + if (elem) { + elem.classList.toggle(activeClass); + } +} + +// Navigation element modification through scrolling +function scrollFunction() { + if (document.documentElement.scrollTop > 0) { + navElement.classList.add("nav-scroll"); + } else { + navElement.classList.remove("nav-scroll"); + } +} + +// Init call +function loadEvent() { + document.addEventListener("scroll", scrollFunction); +} + +// Attach the functions to each event they are interested in +window.addEventListener("load", loadEvent);