diff --git a/src/frontend/src/components/authenticateBox.ts b/src/frontend/src/components/authenticateBox.ts index 070d6304d1..df75a76231 100644 --- a/src/frontend/src/components/authenticateBox.ts +++ b/src/frontend/src/components/authenticateBox.ts @@ -31,7 +31,7 @@ import { signInIcon, } from "./icons"; import { withLoader } from "./loader"; -import { mainWindow } from "./mainWindow"; +import { mainWindowWithSidebar } from "./mainWindowWithSidebar"; import { promptUserNumber } from "./promptUserNumber"; import copyJson from "./authenticateBox.json"; @@ -322,7 +322,7 @@ export const authenticate = async ( // Wrap the template with header & footer and render the page const page = (slot: TemplateResult) => { - const template = mainWindow({ + const template = mainWindowWithSidebar({ slot: html`

Internet Identity

${slot}`, diff --git a/src/frontend/src/components/mainWindowWithSidebar.ts b/src/frontend/src/components/mainWindowWithSidebar.ts new file mode 100644 index 0000000000..60fdb5fe81 --- /dev/null +++ b/src/frontend/src/components/mainWindowWithSidebar.ts @@ -0,0 +1,129 @@ +import { html, TemplateResult } from "lit-html"; +import { ifDefined } from "lit-html/directives/if-defined.js"; +import { footer } from "./footer"; +import { icLogo } from "./icons"; + +import { getDapps } from "$src/flows/dappsExplorer/dapps"; +import { dappsHeader } from "$src/flows/dappsExplorer/teaser"; +import { shuffleArray } from "$src/utils/utils"; + +/** dapps visual used in sidebar */ +const dappsVisual = (): TemplateResult => { + const dapps = shuffleArray(getDapps()); + return dappsHeader({ + dapps, + clickable: false, + }); +}; + +/** + * main window template + * + * To avoid having to repeat the same structure in every page, + * we use this component to wrap the content of each page. + * This way, we can change the structure of the main window + * in one place. + * + * It is a component that includes the logo, the footer, and the container. + * + */ +export const mainWindowWithSidebar = ({ + slot, + id, + showFooter = true, + showLogo = true, + isWideContainer = false, + additionalContainerClasses = [], +}: { + slot: TemplateResult; + id?: string; + showFooter?: boolean; + showLogo?: boolean; + isWideContainer?: boolean; + additionalContainerClasses?: string[]; + HTMLwrapperTag?: string; +}): TemplateResult => { + const containerClasses = ["l-container"]; + if (isWideContainer === true) { + containerClasses.push("l-container--wide"); + } + if (additionalContainerClasses.length > 0) { + containerClasses.push(...additionalContainerClasses); + } + // we do not use the logo from the icons file because it duplicates the the ID's + // (also hides those corresponding IDs in the other instances of the logos when the sidebar is not visible) + return html` +
+ +
+ + ${ + showLogo + ? html`` + : "" + } +
+
${slot}
+
+
+ ${showFooter ? footer : ""} +
+ `; +}; diff --git a/src/frontend/src/styles/main.css b/src/frontend/src/styles/main.css index c5f1c18aeb..dd86e72644 100644 --- a/src/frontend/src/styles/main.css +++ b/src/frontend/src/styles/main.css @@ -139,6 +139,7 @@ --vs-line-height: 1.4; --vs-border-radius: 0.8rem; + --vs-gutter-relative: 5vmax; /* * reference tokens @@ -167,6 +168,9 @@ --rc-background: var(--rc-light); --rc-background-transparent: var(--rc-light-transparent); + --rc-sidebar: var(--vc-brand-purple); + --rc-onSidebar: var(--vc-snow); + --rc-footer: var(--rc-dark); --rc-onFooter: var(--rc-light); @@ -242,6 +246,9 @@ --rg-brand-bruised: var(--vc-brand-blue) 50%, var(--vc-brand-purple) 90%; /* reference tokens: sizes */ + --rs-bezel-layout: var(--vs-gutter-relative); + --rs-bezel-sidebar: calc(var(--vs-gutter-relative) * 0.5); + --rs-inline-grid-gap: var(--vs-inline); --rs-inline-icon-gap: var(--vs-inline); @@ -611,7 +618,38 @@ a:hover, flex-direction: column; align-items: center; min-height: 100vh; - padding: 5vmax; + padding: var(--vs-gutter-relative); +} + +.l-wrap--sidebar { + --sidebar-width: calc(30rem + var(--rs-bezel-sidebar) * 2); + padding-left: var(--sidebar-width); +} + +.l-sidebar { + position: fixed; + left: 0; + top: 0; + bottom: 0; + display: flex; + flex-direction: column; + width: calc(30rem + var(--rs-bezel-sidebar) * 2); + background: var(--rc-sidebar); + color: var(--rc-onSidebar); + padding: var(--rs-bezel-sidebar); +} + +.l-sidebar__main { + flex: 1; + display: flex; + flex-direction: column; + gap: 2rem; +} + +.l-sidebar__decoration { + position: relative; + margin: 0 calc(var(--rs-bezel-sidebar) * -1) + calc(var(--rs-bezel-sidebar) * -1); } @media (max-width: 512px) { @@ -646,6 +684,16 @@ a:hover, right: 0; } +.l-wrap--sidebar .l-footer { + left: var(--sidebar-width); +} + +@media (max-width: 512px) { + .l-wrap--sidebar .l-footer { + left: 0; + } +} + /** * Title with counter and Actions */ @@ -1147,6 +1195,10 @@ by all browsers (FF is missing) */ gap: 1em; } +.c-logo--sidebar { + padding: var(--rs-logo-stack--top) 0 var(--rs-logo-stack--bottom); +} + .c-logo svg { display: block; width: 5.5rem; @@ -2420,6 +2472,18 @@ a.c-action-list__item { display: none !important; } +@media (max-width: 512px) { + .is-hidden--mobile { + display: none !important; + } +} + +@media (min-width: 513px) { + .is-hidden--desktop { + display: none !important; + } +} + .is-visible { display: block !important; }