Skip to content

[Aksel.nav.no] Initial App-router setup #3662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
44258fb
root layout
KenAJoh Mar 11, 2025
3964b75
:sparkles: Added draftmode
KenAJoh Mar 12, 2025
18e7f0f
:sparkles: Setup boilerplate
KenAJoh Mar 13, 2025
9144bc8
:sparkles: Setup grouping-dir
KenAJoh Mar 13, 2025
8205924
Merge branch 'main' into concat-ds
KenAJoh Mar 13, 2025
4b2fc0f
:sparkles: Implemented header
KenAJoh Mar 13, 2025
7019534
:lipstick: Made header sticky
KenAJoh Mar 13, 2025
31ce31a
Merge branch 'main' into concat-ds
KenAJoh Mar 14, 2025
809dfcc
:lock: Content security policy updated
KenAJoh Mar 14, 2025
3690141
:truck: Moved favicon to appdir
KenAJoh Mar 14, 2025
662c69a
:fire: restore old frontpage
KenAJoh Mar 14, 2025
8806361
:truck: Moved sidebar to appdir
KenAJoh Mar 14, 2025
cd48a97
:sparkles: Implemented sidebar loading
KenAJoh Mar 14, 2025
65d8af9
:sparkles: Doc lyout
KenAJoh Mar 14, 2025
ace2b9b
:bug: Add id for skiplink
KenAJoh Mar 14, 2025
234b8fe
:sparkles: Added new footer
KenAJoh Mar 14, 2025
e96a9be
:lipstick: Move skiplink further away
KenAJoh Mar 14, 2025
4bb4bb6
:lipstick: Add more padding bottom sidebar
KenAJoh Mar 14, 2025
299621c
✨ Refactor header and sidebar components for improved layout and stru…
KenAJoh Mar 14, 2025
1b3bda1
:memo: Uncomment some code
KenAJoh Mar 14, 2025
5ac8932
:fire: Removed user server directive from component and layouts
KenAJoh Mar 16, 2025
c0f6cec
:bug: Center footer
KenAJoh Mar 16, 2025
faf0412
:bug: Re-added support for chromatic connect
KenAJoh Mar 16, 2025
8db6965
:fire: removed browser-token
KenAJoh Mar 16, 2025
55a0025
Update aksel.nav.no/website/app/_ui/footer/Footer.tsx
KenAJoh Mar 17, 2025
e3952e6
[Aksel.nav.no] Ported over global search to app-router (#3663)
KenAJoh Mar 17, 2025
b39b66d
[Aksel.nav.no] Move Aksel-brand theme into app-router for use (#3668)
KenAJoh Mar 18, 2025
d0dd060
[Aksel.nav.no] Updated MobileMenu for new ds-pages (#3670)
KenAJoh Mar 18, 2025
f5e8cee
:lipstick: Adjust pressed-sidebar state
KenAJoh Mar 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions aksel.nav.no/website/app/_sanity/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createClient } from "next-sanity";
import { SANITY_API_VERSION, SANITY_PROJECT_ID } from "@/sanity/config";

export const client = createClient({
projectId: SANITY_PROJECT_ID,
dataset: "development",
apiVersion: SANITY_API_VERSION,
useCdn: true,
perspective: "published",
token: process.env.SANITY_READ,
});
16 changes: 16 additions & 0 deletions aksel.nav.no/website/app/_sanity/live.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use server";

import { defineLive } from "next-sanity";
import { client } from "./client";

// set your viewer token
const token = process.env.SANITY_READ;
if (!token) {
throw new Error("Missing SANITY_READ");
}

export const { sanityFetch, SanityLive } = defineLive({
client,
serverToken: token,
browserToken: token,
});
17 changes: 17 additions & 0 deletions aksel.nav.no/website/app/_sanity/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineQuery, groq } from "next-sanity";

const POST_QUERY = defineQuery(`*[_type == "komponent_artikkel"].heading`);

const DESIGNSYSTEM_TYPES = groq`"komponent_artikkel", "ds_artikkel", "templates_artikkel"`;

const DESIGNSYSTEM_SIDEBAR_QUERY =
defineQuery(`*[_type in [${DESIGNSYSTEM_TYPES}] && defined(kategori)] {
_type,
heading,
"slug": slug.current,
kategori,
"tag": status.tag,
"sidebarindex": sidebarindex,
}`);

export { POST_QUERY, DESIGNSYSTEM_SIDEBAR_QUERY };
46 changes: 46 additions & 0 deletions aksel.nav.no/website/app/_ui/footer/Footer.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.footer {
position: relative;
padding-inline: var(--ax-space-48);
padding-block: var(--ax-space-48);
background: var(--ax-bg-brand-blue-moderate);
color: var(--ax-text-neutral);
}

.footerLayout {
max-width: 1440px;
margin-inline: auto;
display: grid;
gap: var(--ax-space-24);
grid-template-columns: repeat(auto-fit, minmax(250px, auto));
}

.footerLogo {
display: flex;
gap: var(--ax-space-16);
flex-direction: column;
}

.footerLinks {
display: grid;
gap: var(--ax-space-12);
}

.footerLink {
display: flex;
width: fit-content;
align-items: center;
gap: var(--ax-space-4);
text-decoration: underline;
color: var(--ax-text-neutral);
text-underline-offset: 0.1em;
border-radius: 1px;

&:hover {
text-decoration-thickness: 0.111em;
}

&:focus-visible {
outline: 3px solid var(--ax-border-focus);
outline-offset: 3px;
}
}
109 changes: 109 additions & 0 deletions aksel.nav.no/website/app/_ui/footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import Link from "next/link";
import { Heading } from "@navikt/ds-react";
import { FigmaIcon, GithubIcon, SlackIcon } from "@/assets/Icons";
import AkselLogo from "@/assets/Logo";
import styles from "./Footer.module.css";

const Footer = () => {
return (
<footer className={`${styles.footer} dark`} id="aksel-footer">
<div className={styles.footerLayout}>
<div className={styles.footerLogo}>
<AkselLogo />
<div>
<p>&copy; {new Date().getFullYear()} Nav</p>
<p>Arbeids- og velferdsetaten</p>
</div>
</div>
<LinkBlock
heading="Snarveier"
links={[
{
url: "/side/skriv-for-aksel",
text: "Skriv for Aksel",
},
{
url: "/prinsipper/brukeropplevelse",
text: "Prinsipper for brukeropplevelse",
},
{ url: "https://sikkerhet.nav.no/", text: "Security Playbook" },
{
url: "https://etterlevelse.ansatt.nav.no/",
text: "Etterlevelse",
},
]}
/>
<LinkBlock
heading="Om nettstedet"
links={[
{
url: "/side/om-aksel",
text: "Hva er Aksel?",
},
{
url: "/personvernerklaering",
text: "Personvernerklæring",
},
{
url: "/side/tilgjengelighetserklaring-for-aksel",
text: "Tilgjengelighetserklæring",
},
]}
/>
<LinkBlock
heading="Finn oss"
links={[
{
url: "https://www.figma.com/@nav_aksel",
text: "Figma",
icon: <FigmaIcon />,
},
{
url: "https://github.com/navikt/aksel",
text: "Github",
icon: <GithubIcon />,
},
{
url: "https://nav-it.slack.com/archives/C7NE7A8UF",
text: "Slack",
icon: <SlackIcon />,
},
]}
/>
</div>
</footer>
);
};

type LinkBlockPropsT = {
heading: string;
links: { url: string; text: string; icon?: React.ReactNode }[];
};

function LinkBlock({ heading, links }: LinkBlockPropsT) {
return (
<div>
<Heading level="2" size="xsmall" spacing>
{heading}
</Heading>
<ul className={styles.footerLinks}>
{links.map((link) => (
<li key={link.url}>
<Link
className={styles.footerLink}
href={link.url}
data-umami-event="navigere"
data-umami-event-kilde="footer"
prefetch={false}
>
{link.icon}
{link.text}
</Link>
</li>
))}
</ul>
</div>
);
}

export default Footer;
29 changes: 29 additions & 0 deletions aksel.nav.no/website/app/_ui/header/Header.link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import styles from "./Header.module.css";

type HeaderLinkProps = {
name: string;
href: string;
};

function HeaderLink({ name, href }: HeaderLinkProps) {
const pathname = usePathname();

return (
<Link
href={href}
prefetch={false}
data-current={pathname?.startsWith(href) ? "true" : "false"}
className={styles.headerLink}
data-umami-event="navigere"
data-umami-event-kilde="header"
>
{name}
</Link>
);
}

export { HeaderLink };
96 changes: 96 additions & 0 deletions aksel.nav.no/website/app/_ui/header/Header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.header {
background-color: var(--ax-bg-default);
position: sticky;
top: 0;
z-index: 1;
border-bottom: 1px solid var(--ax-border-neutral-subtleA);
}

.headerContainer {
/* stylelint-disable-next-line csstools/value-no-unknown-custom-properties */
height: var(--website-header-height);
display: flex;
align-items: center;
padding-inline: 0 var(--ax-space-16);
max-width: 1440px;
margin-inline: auto;

@media (min-width: 1024px) {
padding-inline: 0 var(--ax-space-24);
}
}

.headerLogoLink {
margin-inline: var(--ax-space-8) var(--ax-space-12);
padding-inline: var(--ax-space-8) var(--ax-space-12);
height: 2.75rem;
display: grid;
place-items: center;
border-radius: var(--ax-border-radius-small);

&:focus-visible {
outline: 3px solid var(--ax-border-focus);
outline-offset: 3px;
}
}

.headerLogo {
color: var(--ax-text-neutral);
}

.headerLink {
position: relative;
display: grid;
place-items: center;
height: 2.75rem;
border-radius: var(--ax-border-radius-small);
padding-inline: var(--ax-space-8);
color: var(--ax-text-neutral);

&::before {
content: "";
position: absolute;

/* TODO: revisit with designer */
bottom: var(--ax-space-6);
z-index: 10;
height: 3px;
width: calc(100% - var(--ax-space-16));
border-radius: var(--ax-border-radius-full);
background-color: transparent;
}

&[data-current="true"] {
font-weight: var(--ax-font-weight-bold);

&::before {
background-color: var(--ax-text-neutral);
}
}

&:hover[data-current="false"]::before {
background-color: var(--ax-text-neutral);
}

&:focus-visible {
outline: 3px solid var(--ax-border-focus);
outline-offset: 3px;
}
}

.skiplink {
position: absolute;
left: 0;
background-color: var(--ax-bg-info-strong);
padding: var(--ax-space-16);
color: var(--ax-text-info-contrast);
text-decoration: none;

/* We move it further away to avoid it showing when scroll "overshoots" */
transform: translateY(-300%);

&:focus-within {
transform: translateY(0);
outline: none;
}
}
59 changes: 59 additions & 0 deletions aksel.nav.no/website/app/_ui/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Link from "next/link";
import { Box, HStack, Show, Spacer } from "@navikt/ds-react";
import AkselLogo from "@/assets/Logo";
import { HeaderLink } from "./Header.link";
import styles from "./Header.module.css";

const LINKS = [
{ name: "God praksis", href: "/god-praksis" },
/* { name: "Grunnleggende", href: "/grunnleggende" }, */
/* { name: "Ikoner", href: "/ikoner" }, */
{ name: "Designsystemet", href: "/komponenter-2" },
/* { name: "Mønster & Maler", href: "/monster-maler" }, */
{ name: "Bloggen", href: "/produktbloggen" },
];

function Header() {
return (
<header className={styles.header}>
<a className={styles.skiplink} href="#hovedinnhold">
Hopp til innhold
</a>
<div className={styles.headerContainer}>
<Link
href="/"
passHref
data-umami-event="navigere"
data-umami-event-kilde="header"
className={styles.headerLogoLink}
>
<AkselLogo className={styles.headerLogo} />
<span className="sr-only">Aksel</span>
</Link>

<Spacer />
<Show above="lg" asChild>
<Box
as="nav"
paddingInline={{ xs: "0 space-8", lg: "0 space-32" }}
aria-label="Hovedmeny"
>
<HStack as="ul" gap="space-8" align="center">
{LINKS.map((link) => (
<li key={link.name}>
<HeaderLink name={link.name} href={link.href} />
</li>
))}
</HStack>
</Box>
</Show>
<HStack align="center" gap="2">
{/* <GlobalSearch /> */}
{/* <Hamburger /> */}
</HStack>
</div>
</header>
);
}

export { Header };
Loading
Loading