From 9912188db17e613218d2884d3c462c21ed690d37 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Sun, 29 May 2022 01:31:14 +0300 Subject: [PATCH] web: add dropdown to change langs --- web/comp/page_layout.ts | 27 +++++++++---- web/context.ts | 4 ++ web/static/styles.css | 90 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/web/comp/page_layout.ts b/web/comp/page_layout.ts index 082aaa7..cf11b5d 100644 --- a/web/comp/page_layout.ts +++ b/web/comp/page_layout.ts @@ -1,6 +1,6 @@ import { AnyNode, Attrs, E, Elem } from "ren/node.ts"; import { classNames } from "ren/attrs.ts"; -import { Context, Lang } from "../context.ts"; +import { Context, iterLangs, Lang } from "../context.ts"; export function PageLayout(ctx: Context, children: AnyNode[]): Elem { return E("div", { id: "main" }, [ @@ -31,16 +31,14 @@ function navLink(lhref: string, ctx?: Context): Attrs { } export function Footer(ctx: Context): AnyNode { - return E("footer", classNames("footer gap-v-1x5"), [ - E("div", classNames("content-width"), [ + return E("footer", classNames("footer"), [ + E("div", classNames("content-width gap-v-1x5"), [ Link(ctx.tr.Source_code, { + target: "_blank", href: "https://notabug.org/pleshevskiy/recipes", rel: "external nofollow noopener noreferrer", }), - E("div", [], [ - ChangeLangBtn(ctx, Lang.Rus), - ChangeLangBtn(ctx, Lang.Eng), - ]), + ChangeLang(ctx), ]), ]); } @@ -49,6 +47,21 @@ export function Link(text: string, attrs: Attrs | Attrs[]): AnyNode { return E("a", attrs, text); } +export function ChangeLang(ctx: Context): AnyNode { + const dropdownId = "change_langs"; + return E("div", classNames("dropdown"), [ + E("input", { id: dropdownId, type: "checkbox" }), + E("label", { for: dropdownId }, ctx.lang), + E( + "ul", + [], + iterLangs().filter((l) => l !== ctx.lang).map((l) => + ChangeLangBtn(ctx, l) + ), + ), + ]); +} + export function ChangeLangBtn(ctx: Context, lang: Lang): AnyNode { const prefix = lang === Lang.Rus ? "" : `/${lang}`; return E("a", { "href": prefix + ctx.locPath }, lang); diff --git a/web/context.ts b/web/context.ts index bdec1ce..f9115e3 100644 --- a/web/context.ts +++ b/web/context.ts @@ -6,6 +6,10 @@ export interface Context { tr: Translations; } +export function iterLangs(): Lang[] { + return [Lang.Eng, Lang.Rus]; +} + export enum Lang { Rus = "rus", Eng = "eng", diff --git a/web/static/styles.css b/web/static/styles.css index 66f679f..7da87e7 100644 --- a/web/static/styles.css +++ b/web/static/styles.css @@ -66,6 +66,12 @@ ul, ol { border-top: solid 1px var(--color-gray); } +.footer > .content-width { + display: flex; + flex-direction: row; + justify-content: space-between; +} + .main-menu { display: flex; flex-direction: row; @@ -101,6 +107,8 @@ ul, ol { padding-right: 1.25rem; } +/* responsive typography */ + .responsive-typography h3 { font-size: 24px; } @@ -153,3 +161,85 @@ ul, ol { .responsive-typography li + li { margin-top: 0.5rem; } + +/* dropdown + * Source: https://codepen.io/markcaron/pen/wdVmpB + * + * TODO: change styles + * */ + +.dropdown { + position: relative; + display: inline-block; +} + +.dropdown > input[type="checkbox"] { + position: absolute; + left: -100vw; +} + +.dropdown > label { + display: inline-block; + padding: 6px 15px; + color: #333; + line-height: 1.5em; + text-decoration: none; + border: 1px solid #8c8c8c; + cursor: pointer; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.dropdown > label:hover { + border-color: #333; +} + +.dropdown > label:after { + content: "▲"; + font-size: 10px; + display: inline-block; + margin-left: 6px; + vertical-align: top; +} + +.dropdown > ul { + position: absolute; + z-index: 999; + display: block; + left: -100vw; + bottom: calc(1.5em + 14px); + border: 1px solid #8c8c8c; + background: #fff; + padding: 6px 0; + margin: 0; + list-style: none; + width: 100%; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 3px 8px rgba(0,0,0,.15); + -moz-box-shadow: 0 3px 8px rgba(0,0,0,.15); + box-shadow: 0 3px 8px rgba(0,0,0,.15); +} + +.dropdown > ul a { + display: block; + padding: 6px 15px; + text-decoration: none; + color: #333; +} + +.dropdown > ul a:hover, +.dropdown > ul a:focus { + background: #ececec; +} + +.dropdown > input[type="checkbox"]:checked ~ ul { + left: 0; +} + +.dropdown > [type="checkbox"]:checked + label:after { + content: "▼"; +} +