From 4b8aee8461329297c8f0cdba6d4a2035e5a76844 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Wed, 29 Mar 2023 23:58:40 +0530 Subject: [PATCH 01/11] docs: added cancellation-token content in shutdown docs Cancellation Tokens should be used to notify task to shut down instead of broadcast channels closes #694 --- content/tokio/topics/shutdown.md | 61 ++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/content/tokio/topics/shutdown.md b/content/tokio/topics/shutdown.md index fcbdc13a..6af658b6 100644 --- a/content/tokio/topics/shutdown.md +++ b/content/tokio/topics/shutdown.md @@ -69,33 +69,47 @@ async fn main() { ## Telling things to shut down -The most common tool for telling every part of the application to shut down is -to use a [broadcast channel][broadcast]. The idea is simple: every task in the -application has a receiver for the broadcast channel, and when a message is -broadcast on the channel, the tasks shut themselves down. Usually, receiving -this broadcast message is implemented using [`tokio::select`][select]. For -example, in mini-redis each task receives shutdown in this way: +When you want to tell one or more tasks to shut down, you can use [Cancellation +Tokens][cancellation-tokens]. These tokens allow you to notify tasks that they +should terminate themselves in response to a cancellation request, making it +easy to implement graceful shutdowns. + +To use Cancellation Tokens, you first create a new `CancellationToken`, then +pass it to the tasks that should respond to cancellation requests. When you +want to shut down these tasks gracefully, you call the `cancel` method on the +token, and any task listening to the cancellation request will be notified +to shut down. + ```rs -let next_frame = tokio::select! { - res = self.connection.read_frame() => res?, - _ = self.shutdown.recv() => { - // If a shutdown signal is received, return from `run`. - // This will result in the task terminating. - return Ok(()); +// Step 1: Create a new CancellationToken +let token = CancellationToken::new(); + +// Task 1 - Wait for token cancellation or a long time +tokio::spawn(async move { + tokio::select! { + // Step 2: Listen to cancellation requests + _ = token.cancelled() => { + // The token was cancelled, task can shut down + } + _ = tokio::time::sleep(std::time::Duration::from_secs(9999)) => { + // Long work has completed + } } -}; -``` -In the case of mini-redis, the task immediately terminates when the shutdown -message is received, but in some cases you will need to run a shutdown procedure -before terminating the task. For example, in some cases you need to flush some -data to a file or database before terminating, or if the task manages a -connection, you might want to send a shutdown message on the connection. +}); + +// Task 2 - Cancel the token after a small delay +tokio::spawn(async move { + tokio::time::sleep(std::time::Duration::from_millis(10)).await; -It is usually a good idea to wrap the broadcast channel in a struct. An example -of this can be found [here][shutdown.rs]. + // Step 3: Cancel the token to notify other tasks about shutting down gracefully + token.cancel(); +}); +``` -It's worth mentioning that you can do the same thing using a [watch -channel][watch]. There is no significant difference between the two choices. +With Cancellation Tokens, you don't have to shut down a task immediately when +the token is cancelled. Instead, you can run a shutdown procedure before +terminating the task, such as flushing data to a file or database, or sending +a shutdown message on a connection. ## Waiting for things to finish shutting down @@ -144,6 +158,7 @@ before waiting for the channel to be closed. [an mpsc channel]: https://docs.rs/tokio/1/tokio/sync/mpsc/index.html [select]: https://docs.rs/tokio/1/tokio/macro.select.html [broadcast]: https://docs.rs/tokio/1/tokio/sync/broadcast/index.html +[cancellation-tokens]: https://docs.rs/tokio-util/latest/tokio_util/sync/struct.CancellationToken.html [watch]: https://docs.rs/tokio/1/tokio/sync/watch/index.html [shutdown.rs]: https://github.com/tokio-rs/mini-redis/blob/master/src/shutdown.rs [server.rs]: https://github.com/tokio-rs/mini-redis/blob/master/src/server.rs From b9618bef91a97bdec4c370d0acb39231b4f29982 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Thu, 30 Mar 2023 00:06:17 +0530 Subject: [PATCH 02/11] docs: removed link to broadcast channel in tokio documentation --- content/tokio/topics/shutdown.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/tokio/topics/shutdown.md b/content/tokio/topics/shutdown.md index 6af658b6..a698c92e 100644 --- a/content/tokio/topics/shutdown.md +++ b/content/tokio/topics/shutdown.md @@ -157,7 +157,6 @@ before waiting for the channel to be closed. [ctrl_c]: https://docs.rs/tokio/1/tokio/signal/fn.ctrl_c.html [an mpsc channel]: https://docs.rs/tokio/1/tokio/sync/mpsc/index.html [select]: https://docs.rs/tokio/1/tokio/macro.select.html -[broadcast]: https://docs.rs/tokio/1/tokio/sync/broadcast/index.html [cancellation-tokens]: https://docs.rs/tokio-util/latest/tokio_util/sync/struct.CancellationToken.html [watch]: https://docs.rs/tokio/1/tokio/sync/watch/index.html [shutdown.rs]: https://github.com/tokio-rs/mini-redis/blob/master/src/shutdown.rs From 515d53065c7632413ab21fd07665f1ae955a53ee Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Fri, 31 Mar 2023 02:25:07 +0530 Subject: [PATCH 03/11] docs: added cancellation-token cloning usecase in shutdown docs --- content/tokio/topics/shutdown.md | 36 +++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/content/tokio/topics/shutdown.md b/content/tokio/topics/shutdown.md index a698c92e..5238ec6f 100644 --- a/content/tokio/topics/shutdown.md +++ b/content/tokio/topics/shutdown.md @@ -74,21 +74,34 @@ Tokens][cancellation-tokens]. These tokens allow you to notify tasks that they should terminate themselves in response to a cancellation request, making it easy to implement graceful shutdowns. -To use Cancellation Tokens, you first create a new `CancellationToken`, then -pass it to the tasks that should respond to cancellation requests. When you -want to shut down these tasks gracefully, you call the `cancel` method on the -token, and any task listening to the cancellation request will be notified -to shut down. +Note that, a `CancellationToken` can only be used by one task at a time due to +ownership rule. To use the same `CancellationToken` in multiple tasks you can make +a clone of it. A cloned token can be utilized by another task to either listen for +cancellation requests or to send a cancel request. By using a cloned token, each +task can respond to the cancellation request independently, and you can ensure that +all tasks are properly shut down when the token is canceled. + +Here are the steps to use `CancellationToken` in multiple tasks: +1. First, create a new `CancellationToken`. +2. Then, create a clone of the original `CancellationToken` by calling the `clone` method on the original token. This will create a new token that can be used by another task. +3. Pass the original or cloned token to the tasks that should respond to cancellation requests. +4. When you want to shut down the tasks gracefully, call the `cancel` method on the original or cloned token. Any task listening to the cancellation request on the original or cloned token will be notified to shut down. + + +Here is code snippet showcasing the above mentioned steps: ```rs // Step 1: Create a new CancellationToken let token = CancellationToken::new(); +// Step 2: Clone the token for use in another task +let cloned_token = token.clone(); + // Task 1 - Wait for token cancellation or a long time -tokio::spawn(async move { +let task1_handle = tokio::spawn(async move { tokio::select! { - // Step 2: Listen to cancellation requests - _ = token.cancelled() => { + // Step 3: Using cloned token to listen to cancellation requests + _ = cloned_token.cancelled() => { // The token was cancelled, task can shut down } _ = tokio::time::sleep(std::time::Duration::from_secs(9999)) => { @@ -97,13 +110,16 @@ tokio::spawn(async move { } }); -// Task 2 - Cancel the token after a small delay +// Task 2 - Cancel the original token after a small delay tokio::spawn(async move { tokio::time::sleep(std::time::Duration::from_millis(10)).await; - // Step 3: Cancel the token to notify other tasks about shutting down gracefully + // Step 4: Cancel the original or clonned token to notify other tasks about shutting down gracefully token.cancel(); }); + +// Wait for tasks to complete +task1_handle.await.unwrap() ``` With Cancellation Tokens, you don't have to shut down a task immediately when From f3356944253ead3977f8ac5331381464e27f1821 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sun, 2 Apr 2023 20:39:37 +0530 Subject: [PATCH 04/11] docs: rephrased para explaining CancellationToken usage in graceful shutdown docs --- content/tokio/topics/shutdown.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/content/tokio/topics/shutdown.md b/content/tokio/topics/shutdown.md index 5238ec6f..8ce7102d 100644 --- a/content/tokio/topics/shutdown.md +++ b/content/tokio/topics/shutdown.md @@ -74,12 +74,11 @@ Tokens][cancellation-tokens]. These tokens allow you to notify tasks that they should terminate themselves in response to a cancellation request, making it easy to implement graceful shutdowns. -Note that, a `CancellationToken` can only be used by one task at a time due to -ownership rule. To use the same `CancellationToken` in multiple tasks you can make -a clone of it. A cloned token can be utilized by another task to either listen for -cancellation requests or to send a cancel request. By using a cloned token, each -task can respond to the cancellation request independently, and you can ensure that -all tasks are properly shut down when the token is canceled. +To share a `CancellationToken` between several tasks, you must clone it. This is due +to the single ownership rule that requires that each value has a single owner. When +cloning a token, you get another token that's indistinguishable from the original; +if one is cancelled, then the other is also cancelled. You can make as many clones +as you need, and when you call `cancel` on one of them, they're all cancelled. Here are the steps to use `CancellationToken` in multiple tasks: 1. First, create a new `CancellationToken`. From 0eb49ea9e6cdf95ec756b8d4029af3b01486e579 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sun, 30 Apr 2023 01:27:00 +0530 Subject: [PATCH 05/11] added dark mode styles --- styles/dark-styles.scss | 439 ++++++++++++++++++++++++++++++++++++++++ styles/styles.scss | 4 + 2 files changed, 443 insertions(+) create mode 100644 styles/dark-styles.scss diff --git a/styles/dark-styles.scss b/styles/dark-styles.scss new file mode 100644 index 00000000..d6a0e63e --- /dev/null +++ b/styles/dark-styles.scss @@ -0,0 +1,439 @@ +/** COLOR VALUES */ +$surface-100: #1B1B1B; // For body background color +$surface-200: #1F1F1F; // For cards, aside, sidebars background color +$surface-250: #242424; +$surface-300: #2D2D2D; // Navbar - For chips buttons, dropdowns background color +$surface-400: #353535; // For sidebars, navbar background color +$surface-500: #3D3D3D; // For modal, dialogs background color +$surface-600: #404040; // divider, hr, border +$surface-700: #696969; // For on background texts color | 267 0 41 + +$light-gray: #D6D6D6; // hover on secondary text +$gray: #A0A0A0; // secondary text +$dark-gray: #939393; // code snippet text + +$magenta-100: #DE46A9; // Normal +$magenta-200: #E25AB2; // Light + +$pure-white: #ffffff; +$white: #F0F0F0; // text, title +$red: #e7544c; +$orange: #f5a623; +$black-pink: #211E21; +$purple: #B284EB; +$green: #81C42C; +$yellow: #DDB218; +$blue: #4197E3; +$lightblue: #56A3E6; + +// Each color is associated with a library +$tk-lib-runtime: $magenta-100; +$tk-lib-hyper: $orange; +$tk-lib-tonic: $yellow; +$tk-lib-tower: $green; +$tk-lib-mio: $red; +$tk-lib-tracing: $purple; +$tk-lib-bytes: $blue; + + +// Per lib styling: [ name, bg-color, color, size, logo-adjust ] +$libs: "tokio" $white $surface-100 3.8rem -60%, "runtime" darken($tk-lib-runtime) $pure-white 2.2rem -22%, + "hyper" $tk-lib-hyper $surface-100 100% -50%, "tonic" $tk-lib-tonic $surface-100 100% -25%, + "tower" $tk-lib-tower $surface-100 100% -52%, "mio" $tk-lib-mio $surface-100 100% -41%, + "tracing" $tk-lib-tracing $surface-100 100% -31%, "bytes" $tk-lib-bytes $surface-100 100% -30%; + +body { + background-color: $surface-100; + color: $white; +} + +.navbar { + background-color: $surface-400; + + .navbar-burger { + color: $white; + } + + .navbar-link, + .navbar-item { + color: $white; + + &:hover, + &:focus, + &:focus-within, + &.is-active { + background-color: initial; + color: $magenta-200; + } + } + .navbar-brand, .navbar-menu { + background-color: $surface-400; + } + hr { + background-color: $gray; + } +} + + +.hero { + &.is-primary { + background-color: $surface-200; + .title, .subtitle { + color: $white; + } + } + &.tk-intro { + .button { + background-color: $magenta-100; + } + .button:hover { + background-color: $magenta-200; + } + .title, .subtitle { + color: $white; + } + } + &.tk-users { + background-color: $surface-100; + + .title, .subtitle { + color: $white; + } + + .image { + img { + filter: invert(0.95); + } + } + } +} + +.tk-features, +.tk-stack { + code { + background-color: $surface-400; + color: $white; + } +} + +.tk-features { + background-color: $surface-200; + + .card { + background-color: $surface-250; + border: 2px solid $white; + } + + @each $name, $bgColor, $color, $size, $adjust in $libs { + .tk-lib-#{$name} { + .title, + .learn-more a { + color: $bgColor; + } + .learn-more a:hover { + color: darken($bgColor); + } + .card { + border-color: $bgColor; + } + } + } +} + +.card { + background-color: $surface-200; +} + +.tk-stack { + background-color: $surface-100; + + .menu { + @each $name, $bgColor, $color, $size, $adjust in $libs { + .tk-lib-#{$name} { + a:hover { + color: $bgColor; + } + + a { + color: $gray; + } + + &.is-active { + background-color: $bgColor; + + a { + color: $color; + } + } + } + } + } + + // Per lib styling + @each $name, $bgColor, $color, $size, $adjust in $libs { + .tk-lib-#{$name} { + .title, + .learn-more a { + color: $bgColor; + } + .title img { + vertical-align: $adjust; + height: $size; + } + } + } + + .tk-lib-tokio { + .title img { + filter: invert(1); + } + } +} + +.tk-docs { + .tk-docs-nav { + background-color: $surface-200; + } + + .menu { + @include mobile { + .tk-toc { + background-color: $surface-200; + + a { + color: $white; + } + + .tk-arrow { + &:before, + &:after { + background-color: $white; + } + } + } + + .tk-menu-body { + background-color: $surface-200; + } + } + + .menu-label { + color: $gray; + } + .menu-list { + a { + color: $gray; + + &:hover { + color: $magenta-200; + } + } + + } + + li.is-active { + background-color: $surface-100; + + > a { + color: $white; + } + } + } + + .tk-content { + background-color: $surface-100; + color: $white; + + .tk-content-summary { + a { + color: $gray; + + &:hover { + color: $light-gray; + } + } + + > ul { + border-left: solid 1px $surface-600; + } + } + + h1:not(.title) { + border-bottom: solid 1px $surface-600; + } + + a { + color: $magenta-100; + } + a:hover { + color: $magenta-200; + } + + .tk-markdown { + .is-warning { + background: $black-pink; + color: $light-gray;// $magenta-100; + + strong, + code { + color: $magenta-100; + } + } + + blockquote.is-warning { + border-left-color: $magenta-100; + } + } + + code { + color: $white; + } + + a code { + color: $magenta-100; + } + a:hover code { + color: $magenta-200; + } + } +} + +.content h1, +.content h2, +.content h3, +.content h4, +.content h5, +.content h6, +strong { + color: $white; +} + +.content blockquote { + background-color: $surface-200; + border-color: $surface-600; +} + +.footer { + color: $white; + background-color: $surface-400; + + a { + color: $magenta-100; + + &:hover { + color: $magenta-200; + } + } + + .tk-footer-libs { + a:hover { + color: $magenta-100; + } + } + + .tk-footer-libs, + .tk-footer-libs a, + .tk-sponsored, + .tk-sponsored a { + color: $white; + } +} + +.tk-doc-footer { + border-top: 1px solid $surface-600; + + .tk-help-links { + .tk-svg-path { + fill: $white !important; + } + } +} + +/* + * + * Syntax highlighting + * + */ + +pre, code { + background-color: $surface-250; +} + +.hljs-comment, +.hljs-quote { + color: $dark-gray; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: $magenta-100; +} + +.hljs-number { + color: $green; +} + +.hljs-string, +.hljs-doctag { + color: $green; +} + +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: $blue; +} + +.hljs-params { + color: $purple; +} + +.hljs-title { + color: $purple; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: $lightblue; +} + +.hljs-variable, +.hljs-template-variable { + color: $green; +} + +.hljs-regexp, +.hljs-link { + color: $green; +} + +.hljs-symbol, +.hljs-bullet { + color: $purple; +} + +.hljs-built_in, +.hljs-builtin-name { + color: $yellow; +} + +.hljs-meta { + color: $dark-gray; +} + +.hljs-deletion { + background: $red; +} + +.hljs-addition { + background: $green; +} + +.all-posts-link { + a { + color: $magenta-100; + } +} diff --git a/styles/styles.scss b/styles/styles.scss index 8812ec17..c5d03390 100644 --- a/styles/styles.scss +++ b/styles/styles.scss @@ -1035,3 +1035,7 @@ Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine .blog-year-posts ul { margin-bottom: 2rem; } + +@media (prefers-color-scheme: dark) { + @import "./dark-styles.scss"; +} From d5f2ef2a3df41efd9d3845c1ed44e2502545c4ef Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sun, 30 Apr 2023 01:27:09 +0530 Subject: [PATCH 06/11] minor fix --- styles/styles.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/styles.scss b/styles/styles.scss index c5d03390..0d622fce 100644 --- a/styles/styles.scss +++ b/styles/styles.scss @@ -1024,7 +1024,7 @@ Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine a { font-weight: 500; - color: #c83895; + color: $magenta; } @include mobile { From 1a428975d1863267766e25eea47c923a8e6b06c0 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sat, 6 May 2023 21:40:30 +0530 Subject: [PATCH 07/11] feat: added toggle theme button --- components/icons.tsx | 30 +++++++++++++++++++-- components/nav.tsx | 3 +++ components/toggle-theme.tsx | 33 +++++++++++++++++++++++ hooks/use-theme.ts | 54 +++++++++++++++++++++++++++++++++++++ pages/_app.tsx | 4 +++ styles/dark-styles.scss | 5 ++++ styles/styles.scss | 54 ++++++++++++++++++++++++++++++++++++- 7 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 components/toggle-theme.tsx create mode 100644 hooks/use-theme.ts diff --git a/components/icons.tsx b/components/icons.tsx index 148168a1..cd106526 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -7,17 +7,21 @@ type Props = { children: ReactNode; className?: string; viewBox?: string; + width?: number | `${number}`; + height?: number | `${number}`; }; const Icon: FC = ({ children, className = "", viewBox = DEFAULT_VIEW_BOX, + width = "45", + height = "45" }) => ( @@ -66,3 +70,25 @@ export function DiscordIcon({ className = "" }) { ); } + +export function LightThemeIcon({ className = "" }) { + return ( + + + + ); +} + +export function DarkThemeIcon({ className = "" }) { + return ( + + + + ); +} diff --git a/components/nav.tsx b/components/nav.tsx index b722bd3a..d2270436 100644 --- a/components/nav.tsx +++ b/components/nav.tsx @@ -1,6 +1,7 @@ import React, { FC, useCallback, useState } from "react"; import classnames from "classnames"; import SocialLinks from "./social-links"; +import ToggleTheme from "./toggle-theme"; // TODO: what is this thing?? type Blog = any; @@ -68,6 +69,8 @@ const Navigation: FC<{ blog: Blog }> = ({ blog }) => {
+ +
diff --git a/components/toggle-theme.tsx b/components/toggle-theme.tsx new file mode 100644 index 00000000..3a7e8094 --- /dev/null +++ b/components/toggle-theme.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import { DarkThemeIcon, LightThemeIcon } from "./icons"; + +const ToggleTheme: React.FC = () => { + /** + * Handles theme change + */ + const toggleTheme = () => { + const THEME_KEY = 'data-theme'; + + // getting current theme from body element + const currentTheme = document.body.getAttribute(THEME_KEY); + + // new theme, opposite to current theme + const newTheme = currentTheme === 'light' ? 'dark' : 'light'; + + // set new theme on body element + document.body.setAttribute(THEME_KEY, newTheme); + // set new theme in local storage + localStorage.setItem(THEME_KEY, newTheme); + }; + + return ( +
+ +
+ ); +}; + +export default ToggleTheme; diff --git a/hooks/use-theme.ts b/hooks/use-theme.ts new file mode 100644 index 00000000..07dc2d2d --- /dev/null +++ b/hooks/use-theme.ts @@ -0,0 +1,54 @@ +import React from "react"; + +// This supresses the `useLayoutEffect` usage warning on server side +if (typeof window === 'undefined') { + React.useLayoutEffect = () => {} +} + +let initDone = false; + +export const useTheme = () => { + + // This effect selects the theme from preferences or storage + React.useLayoutEffect(() => { + if (initDone) { + // return early if the effect has ran once + return; + } + initDone = true; + + // getting theme value from local storage + const savedTheme = localStorage.getItem('data-theme'); + if (savedTheme) { + // if user has theme in localStorage, set it on body element + document.body.setAttribute('data-theme', savedTheme); + return; + } + + // When localStorage does not contain theme value + // Read user color preference on device + const darkModePreferred = matchMedia('(prefers-color-scheme: dark)').matches; + // set theme value on body element as per device preference + document.body.setAttribute('data-theme', darkModePreferred ? 'dark' : 'light'); + }, []); + + + // This effects adds the change listener on "prefers-color-scheme: dark" media query + React.useEffect(() => { + // Preferred Theme Media Query + const themeMediaQuery = matchMedia('(prefers-color-scheme: dark)'); + + // Handles preferred color scheme change + function onPreferColorSchemeChange(event: MediaQueryListEvent) { + // Remove saved theme data in localStorage on change of theme preference + localStorage.removeItem('data-theme'); + // Setting new preferred theme on body element + document.body.setAttribute('data-theme', event.matches ? 'dark' : 'light'); + } + + themeMediaQuery.addEventListener("change", onPreferColorSchemeChange); + return () => { + themeMediaQuery.removeEventListener("change", onPreferColorSchemeChange); + } + }, []); +} diff --git a/pages/_app.tsx b/pages/_app.tsx index 8c1e9645..84a17011 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -2,8 +2,12 @@ import React from "react"; import { AppProps } from "next/app"; import "../styles/styles.scss"; +import { useTheme } from "../hooks/use-theme"; function MyApp({ Component, pageProps }: AppProps) { + // Handle Theme Selection on client side + useTheme(); + return ; } diff --git a/styles/dark-styles.scss b/styles/dark-styles.scss index d6a0e63e..dd5357b9 100644 --- a/styles/dark-styles.scss +++ b/styles/dark-styles.scss @@ -74,6 +74,11 @@ body { } } +.toggle-theme__btn { + &:hover { + background-color: $black-pink; + } +} .hero { &.is-primary { diff --git a/styles/styles.scss b/styles/styles.scss index 0d622fce..f8db2999 100644 --- a/styles/styles.scss +++ b/styles/styles.scss @@ -96,6 +96,46 @@ a:active { overscroll-behavior-y: none; } +.toggle-theme { + &__container { + width: 2rem; + height: 2rem; + margin: 0 1.5rem; + } + + &__btn { + // button style reset/cleanup + background: none; + border: none; + color: inherit; + cursor: pointer; + font-family: inherit; + padding: 0; + -webkit-tap-highlight-color: transparent; + + // custom styles + width: 100%; + height: 100%; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: background 200ms; + + &:hover { + background-color: darken($dark-gray); + } + } + + body[data-theme=dark] &__icon--light { + display: none; + } + + body:not([data-theme=dark]) &__icon--dark { + display: none; + } +} + .navbar { .navbar-brand { background-color: black; @@ -1036,6 +1076,18 @@ Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine margin-bottom: 2rem; } -@media (prefers-color-scheme: dark) { +//#region Dark Theme Styles + +// Applying dark theme when body has dark atribute, not matter the theme preference +body[data-theme=dark] { @import "./dark-styles.scss"; } + +// When body element has light theme data and the theme preference is set to dark, Use light theme +@media (prefers-color-scheme: dark) { + body:not([data-theme="light"]) { + @import "./dark-styles.scss"; + } +} + +//#endregion Dark Theme Styles From 9f2aa3b1ff85a8d2820eea2ca46a5536f8b85698 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sat, 6 May 2023 21:41:28 +0530 Subject: [PATCH 08/11] fix: toggle button and navbar style fixes --- styles/styles.scss | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/styles/styles.scss b/styles/styles.scss index f8db2999..330be188 100644 --- a/styles/styles.scss +++ b/styles/styles.scss @@ -103,6 +103,21 @@ a:active { margin: 0 1.5rem; } + // Reducing whitespace around toggle button to make it consistent + // with other navbar links and icons on breakpoint: mobile < 800px < tablet/desktop + @include until(800px) { + &__container { + margin: 0 0.85rem; + } + } + + @include mobile { + &__container { + margin: 0 1.5rem; + margin-bottom: 1.5rem; + } + } + &__btn { // button style reset/cleanup background: none; @@ -165,6 +180,22 @@ a:active { } } + // Reducing whitespace in navbar to fit links and icons + // on breakpoint: mobile < 800px < tablet/desktop + @include until(800px) { + .navbar-item { + &.navbar-text { + padding: 0 0.85rem; + } + &.navbar-icon { + padding: 0 0.85rem; + } + } + hr { + margin: 1rem 0.85rem; + } + } + @include mobile { .navbar-menu { display: block; @@ -190,6 +221,10 @@ a:active { &:first-child { margin-top: 0.5rem; } + // Resetting reduced whitespace to normal + &.navbar-text, &.navbar-icon { + padding: 0 1.5rem; + } } .tk-social, From c8ad43b10a3a7263a12a8e232f98ed373766a6a4 Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sat, 6 May 2023 23:21:20 +0530 Subject: [PATCH 09/11] fix: color contrast fixes --- styles/dark-styles.scss | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/styles/dark-styles.scss b/styles/dark-styles.scss index dd5357b9..b434531e 100644 --- a/styles/dark-styles.scss +++ b/styles/dark-styles.scss @@ -12,8 +12,10 @@ $light-gray: #D6D6D6; // hover on secondary text $gray: #A0A0A0; // secondary text $dark-gray: #939393; // code snippet text -$magenta-100: #DE46A9; // Normal -$magenta-200: #E25AB2; // Light +$magenta-000: #C63995; +$magenta-100: #DE46A9; +$magenta-200: #E25AB2; +$magenta-300: #E670BD; $pure-white: #ffffff; $white: #F0F0F0; // text, title @@ -27,7 +29,7 @@ $blue: #4197E3; $lightblue: #56A3E6; // Each color is associated with a library -$tk-lib-runtime: $magenta-100; +$tk-lib-runtime: $magenta-200; $tk-lib-hyper: $orange; $tk-lib-tonic: $yellow; $tk-lib-tower: $green; @@ -37,7 +39,7 @@ $tk-lib-bytes: $blue; // Per lib styling: [ name, bg-color, color, size, logo-adjust ] -$libs: "tokio" $white $surface-100 3.8rem -60%, "runtime" darken($tk-lib-runtime) $pure-white 2.2rem -22%, +$libs: "tokio" $white $surface-100 3.8rem -60%, "runtime" $tk-lib-runtime $surface-100 2.2rem -22%, "hyper" $tk-lib-hyper $surface-100 100% -50%, "tonic" $tk-lib-tonic $surface-100 100% -25%, "tower" $tk-lib-tower $surface-100 100% -52%, "mio" $tk-lib-mio $surface-100 100% -41%, "tracing" $tk-lib-tracing $surface-100 100% -31%, "bytes" $tk-lib-bytes $surface-100 100% -30%; @@ -89,10 +91,10 @@ body { } &.tk-intro { .button { - background-color: $magenta-100; + background-color: $magenta-000; } .button:hover { - background-color: $magenta-200; + background-color: $magenta-100; } .title, .subtitle { color: $white; @@ -281,12 +283,12 @@ body { strong, code { - color: $magenta-100; + color: $magenta-200; } } blockquote.is-warning { - border-left-color: $magenta-100; + border-left-color: $magenta-200; } } @@ -295,10 +297,10 @@ body { } a code { - color: $magenta-100; + color: $magenta-200; } a:hover code { - color: $magenta-200; + color: $magenta-300; } } } @@ -313,9 +315,18 @@ strong { color: $white; } -.content blockquote { +.content blockquote, +.content blockquote.is-info { background-color: $surface-200; border-color: $surface-600; + + a { + color: $magenta-200; + + &:hover { + color: $magenta-300; + } + } } .footer { @@ -372,7 +383,7 @@ pre, code { .hljs-keyword, .hljs-selector-tag, .hljs-subst { - color: $magenta-100; + color: $magenta-200; } .hljs-number { From 62c474c8fee592eab4913253f14478b7533413ac Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sat, 6 May 2023 23:36:31 +0530 Subject: [PATCH 10/11] footer color contrast issue --- styles/dark-styles.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/styles/dark-styles.scss b/styles/dark-styles.scss index b434531e..6c350af7 100644 --- a/styles/dark-styles.scss +++ b/styles/dark-styles.scss @@ -334,10 +334,10 @@ strong { background-color: $surface-400; a { - color: $magenta-100; + color: $lightblue; &:hover { - color: $magenta-200; + color: $blue; } } From 16f22eaffb4add5b0c917f3b9e3ab644a85b7a3c Mon Sep 17 00:00:00 2001 From: Jatin Nagar Date: Sun, 7 May 2023 19:12:25 +0530 Subject: [PATCH 11/11] fix: :bug: empty white space on large resolutions in dark theme --- styles/dark-styles.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/styles/dark-styles.scss b/styles/dark-styles.scss index 6c350af7..2bb0648e 100644 --- a/styles/dark-styles.scss +++ b/styles/dark-styles.scss @@ -198,6 +198,8 @@ body { } .tk-docs { + background-color: $surface-100; + .tk-docs-nav { background-color: $surface-200; }