Skip to content

Commit 7c35584

Browse files
authored
[Aksel.nav.no] Grid-layouts and Porting of more components (#3683)
* ✨ Setup new layout grid * ♻️ PortableText config setup * ✨ Migrated over Blocks support to appdir * 🚚 Moved typo components to appdir * ✨ Add Komponent spesific modules to page template * ✨ Added thumbnail (hardcoded) * ✨ Introduced DesignsystemetKomponentIntro and DesignsystemetThumbnail components for enhanced component documentation * 🐛 TOC is now sticky * ✨ Added marks-support (#3684)
1 parent 5d917e1 commit 7c35584

25 files changed

+892
-59
lines changed

aksel.nav.no/website/app/_sanity/queries.ts

+5
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,14 @@ const TOC_BY_SLUG_QUERY =
5959
"title": pt::text(@)
6060
}`);
6161

62+
const SLUG_BY_TYPE_QUERY = defineQuery(`
63+
*[_type == $type && defined(slug.current)].slug.current
64+
`);
65+
6266
export {
6367
DESIGNSYSTEM_SIDEBAR_QUERY,
6468
GLOBAL_SEARCH_QUERY_ALL,
6569
KOMPONENT_BY_SLUG_QUERY,
6670
TOC_BY_SLUG_QUERY,
71+
SLUG_BY_TYPE_QUERY,
6772
};

aksel.nav.no/website/app/_sanity/query-types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -4508,6 +4508,9 @@ export type TOC_BY_SLUG_QUERYResult = Array<{
45084508
id: string;
45094509
title: string;
45104510
}> | null;
4511+
// Variable: SLUG_BY_TYPE_QUERY
4512+
// Query: *[_type == $type && defined(slug.current)].slug.current
4513+
export type SLUG_BY_TYPE_QUERYResult = Array<string | null>;
45114514

45124515
declare module "@sanity/client" {
45134516
interface SanityQueries {
@@ -4516,5 +4519,6 @@ declare module "@sanity/client" {
45164519
'*[_type in ["komponent_artikkel",\n "ds_artikkel",\n "aksel_artikkel",\n "aksel_blogg",\n "aksel_prinsipp",\n "aksel_standalone",\n "templates_artikkel"]]{\n heading,\n "slug": slug.current,\n "tema": undertema[]->tema->title,\n ingress,\n status,\n _type,\n "intro": pt::text(intro.body),\n content,\n publishedAt,\n seo\n}': GLOBAL_SEARCH_QUERY_ALLResult;
45174520
'*[_type == "komponent_artikkel" && slug.current == $slug][0]\n {\n ...,\n intro{\n ...,\n body[]{\n ...,\n \n_type == "language" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "attachment" =>{\n ...,\n "downloadLink": asset->url,\n "size": asset->size,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "token_ref"=>@->,\n\nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n},\n_type == "intro_komponent" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n},\n_type == "innholdskort" =>{\n ...,\n "lenke": lenke->slug.current,\n},\n_type == "live_demo" =>{\n ...,\n "sandbox_ref": sandbox_ref->{...},\n},\n_type == "props_seksjon" =>{\n ...,\n komponenter[]{\n ...,\n "propref": propref->{...}\n },\n},\n_type == "installasjon_seksjon" =>{\n ...,\n "code_ref": code_ref->{...},\n},\n_type == "spesial_seksjon" =>{\n ...,\n modul == "komponentoversikt" =>{\n "komponenter": *[_type == \'komponent_artikkel\' && !(_id in path("drafts.**"))]{\n _id,\n heading,\n "ingress": intro.body,\n status,\n slug,\n }\n },\n modul == "token_kategori" =>{\n "token": token_ref->{...}\n}\n},\n_type == "accordion"=>{\n ...,\n list[]{\n ...,\n content[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n},\n \n _type == "riktekst_blokk" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "bilde" =>{\n ...,\n floating_text[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "video" =>{\n ...,\n "webm": {\n "url": webm.asset->url,\n "extension": webm.asset->extension\n },\n "fallback": {\n "url": fallback.asset->url,\n "extension": fallback.asset->extension\n },\n "track": track.asset->url\n },\n _type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "kode" =>{\n ...,\n "ref": ref->{...},\n },\n _type == "kode_eksempler" =>{\n ...,\n dir->,\n },\n _type == "kode_ref" => @->,\n _type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n _type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n}\n\n }\n }\n}\n,\n_type == "expansioncard"=>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n},\n \n _type == "riktekst_blokk" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "bilde" =>{\n ...,\n floating_text[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "video" =>{\n ...,\n "webm": {\n "url": webm.asset->url,\n "extension": webm.asset->extension\n },\n "fallback": {\n "url": fallback.asset->url,\n "extension": fallback.asset->extension\n },\n "track": track.asset->url\n },\n _type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "kode" =>{\n ...,\n "ref": ref->{...},\n },\n _type == "kode_eksempler" =>{\n ...,\n dir->,\n },\n _type == "kode_ref" => @->,\n _type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n _type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n}\n\n }\n},\n\n _type == "riktekst_blokk" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "bilde" =>{\n ...,\n floating_text[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "video" =>{\n ...,\n "webm": {\n "url": webm.asset->url,\n "extension": webm.asset->extension\n },\n "fallback": {\n "url": fallback.asset->url,\n "extension": fallback.asset->extension\n },\n "track": track.asset->url\n },\n _type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "kode" =>{\n ...,\n "ref": ref->{...},\n },\n _type == "kode_eksempler" =>{\n ...,\n dir->,\n },\n _type == "kode_ref" => @->,\n _type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n _type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n}\n,\n\n }\n },\n content[]{\n ...,\n \n_type == "language" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "attachment" =>{\n ...,\n "downloadLink": asset->url,\n "size": asset->size,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "token_ref"=>@->,\n\nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n},\n_type == "intro_komponent" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n_type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n},\n_type == "innholdskort" =>{\n ...,\n "lenke": lenke->slug.current,\n},\n_type == "live_demo" =>{\n ...,\n "sandbox_ref": sandbox_ref->{...},\n},\n_type == "props_seksjon" =>{\n ...,\n komponenter[]{\n ...,\n "propref": propref->{...}\n },\n},\n_type == "installasjon_seksjon" =>{\n ...,\n "code_ref": code_ref->{...},\n},\n_type == "spesial_seksjon" =>{\n ...,\n modul == "komponentoversikt" =>{\n "komponenter": *[_type == \'komponent_artikkel\' && !(_id in path("drafts.**"))]{\n _id,\n heading,\n "ingress": intro.body,\n status,\n slug,\n }\n },\n modul == "token_kategori" =>{\n "token": token_ref->{...}\n}\n},\n_type == "accordion"=>{\n ...,\n list[]{\n ...,\n content[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n},\n \n _type == "riktekst_blokk" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "bilde" =>{\n ...,\n floating_text[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "video" =>{\n ...,\n "webm": {\n "url": webm.asset->url,\n "extension": webm.asset->extension\n },\n "fallback": {\n "url": fallback.asset->url,\n "extension": fallback.asset->extension\n },\n "track": track.asset->url\n },\n _type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "kode" =>{\n ...,\n "ref": ref->{...},\n },\n _type == "kode_eksempler" =>{\n ...,\n dir->,\n },\n _type == "kode_ref" => @->,\n _type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n _type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n}\n\n }\n }\n}\n,\n_type == "expansioncard"=>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n},\n \n _type == "riktekst_blokk" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "bilde" =>{\n ...,\n floating_text[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "video" =>{\n ...,\n "webm": {\n "url": webm.asset->url,\n "extension": webm.asset->extension\n },\n "fallback": {\n "url": fallback.asset->url,\n "extension": fallback.asset->extension\n },\n "track": track.asset->url\n },\n _type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "kode" =>{\n ...,\n "ref": ref->{...},\n },\n _type == "kode_eksempler" =>{\n ...,\n dir->,\n },\n _type == "kode_ref" => @->,\n _type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n _type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n}\n\n }\n},\n\n _type == "riktekst_blokk" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "bilde" =>{\n ...,\n floating_text[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "video" =>{\n ...,\n "webm": {\n "url": webm.asset->url,\n "extension": webm.asset->extension\n },\n "fallback": {\n "url": fallback.asset->url,\n "extension": fallback.asset->extension\n },\n "track": track.asset->url\n },\n _type == "alert" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n },\n _type == "kode" =>{\n ...,\n "ref": ref->{...},\n },\n _type == "kode_eksempler" =>{\n ...,\n dir->,\n },\n _type == "kode_ref" => @->,\n _type == "tips" =>{\n ...,\n body[]{\n ...,\n \nmarkDefs[]{\n ...,\n _type == \'internalLink\' => {\n "slug": @.reference->slug,\n },\n}\n }\n},\n _type == "relatert_innhold" =>{\n title,\n lenker[]{\n ...,\n "intern_lenke": intern_lenke->slug.current,\n }\n}\n,\n\n },\n}': KOMPONENT_BY_SLUG_QUERYResult;
45184521
'*[slug.current == $slug][0].content[style match \'h2\'][]{\n "id": _key,\n "title": pt::text(@)\n}': TOC_BY_SLUG_QUERYResult;
4522+
"\n *[_type == $type && defined(slug.current)].slug.current\n": SLUG_BY_TYPE_QUERYResult;
45194523
}
45204524
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import createImageUrlBuilder from "@sanity/image-url";
2+
import type { Image } from "sanity";
3+
import { SANITY_DATASET, SANITY_PROJECT_ID } from "@/sanity/config";
4+
5+
const imageBuilder = createImageUrlBuilder({
6+
projectId: SANITY_PROJECT_ID || "",
7+
dataset: SANITY_DATASET || "",
8+
});
9+
10+
const urlForImage = (source: Image | null | undefined) => {
11+
// Ensure that source image contains a valid reference
12+
if (!source?.asset?._ref) {
13+
return undefined;
14+
}
15+
16+
return imageBuilder?.image(source).auto("format").fit("max");
17+
};
18+
19+
function urlForOpenGraphImage(image: Image | null | undefined) {
20+
return urlForImage(image)?.width(1200).height(627).fit("crop").url();
21+
}
22+
23+
export { urlForImage, urlForOpenGraphImage };

aksel.nav.no/website/app/_ui/global-search/GlobalSearch.hit.tsx

+2-12
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,10 @@ import React from "react";
66
import { Heading } from "@navikt/ds-react";
77
import { urlFor } from "@/sanity/interface";
88
import { StatusTag } from "@/web/StatusTag";
9+
import { doctypeToColorRole } from "../theme-config";
910
import { SearchHitT, SearchResultPageTypesT } from "./GlobalSearch.config";
1011
import styles from "./GlobalSearch.module.css";
1112

12-
/* TODO: Move this to global Aksel-config */
13-
const doctypeToRole: Record<SearchResultPageTypesT, string> = {
14-
ds_artikkel: "brand-blue",
15-
komponent_artikkel: "brand-blue",
16-
templates_artikkel: "brand-blue",
17-
aksel_artikkel: "aksel-brand-teal",
18-
aksel_blogg: "aksel-brand-pink",
19-
aksel_prinsipp: "neutral",
20-
aksel_standalone: "neutral",
21-
};
22-
2313
function GlobalSearchHitCollection({
2414
heading,
2515
searchHits,
@@ -39,7 +29,7 @@ function GlobalSearchHitCollection({
3929
className={styles.searchSectionHeading}
4030
size="small"
4131
level="2"
42-
data-color-role={doctypeToRole[tag ?? ""] ?? "neutral"}
32+
data-color-role={doctypeToColorRole[tag ?? ""] ?? "neutral"}
4333
>
4434
{heading}
4535
</Heading>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import {
2+
PortableTextBlockComponent,
3+
type PortableTextComponents,
4+
PortableTextMarkComponent,
5+
} from "next-sanity";
6+
import { Children } from "react";
7+
import { BodyLong, BodyShort, Detail, Heading } from "@navikt/ds-react";
8+
import { Kbd } from "../kbd/Kbd";
9+
import { Code } from "../typography/Code";
10+
import { List, ListItem } from "../typography/List";
11+
import { WebsiteLink } from "../typography/WebsiteLink";
12+
import styles from "./CustomPortableText.module.css";
13+
14+
type CustomPortableTextComponentsProps = {
15+
typoConfig?: {
16+
size?: "small" | "medium" | "large";
17+
type: "short" | "long";
18+
};
19+
};
20+
21+
function customPortableTextComponents({
22+
typoConfig,
23+
}: CustomPortableTextComponentsProps): PortableTextComponents {
24+
const block = blockComponents({ typoConfig });
25+
const marks = marksComponents();
26+
27+
return {
28+
block,
29+
list: {
30+
bullet: ({ children }) => <List as="ul">{children}</List>,
31+
number: ({ children }) => <List as="ol">{children}</List>,
32+
},
33+
listItem: {
34+
bullet: ({ children }) => <ListItem icon>{children}</ListItem>,
35+
number: ({ children }) => <ListItem>{children}</ListItem>,
36+
},
37+
marks,
38+
unknownBlockStyle: ({ children }) =>
39+
withSanitizedBlock(<BodyShort spacing>{children}</BodyShort>),
40+
unknownType: () => null,
41+
unknownMark: () => null,
42+
};
43+
}
44+
45+
function marksComponents() {
46+
return {
47+
kbd: ({ text }) => <Kbd>{text}</Kbd>,
48+
quote: ({ text }) => <q>{text}</q>,
49+
code: ({ text }) => <Code>{text}</Code>,
50+
51+
link: ({ text, value: { href } }) => {
52+
if (!href) {
53+
return <span>{text}</span>;
54+
}
55+
return <WebsiteLink href={href}>{text}</WebsiteLink>;
56+
},
57+
internalLink: ({ text, value: { slug } }) => {
58+
if (!slug || !slug.current) {
59+
return <span>{text}</span>;
60+
}
61+
return <WebsiteLink href={`/${slug.current}`}>{text}</WebsiteLink>;
62+
},
63+
} satisfies Record<string, PortableTextMarkComponent>;
64+
}
65+
66+
function blockComponents({
67+
typoConfig = { type: "long", size: "medium" },
68+
}: CustomPortableTextComponentsProps) {
69+
const BodyComponent = typoConfig.type === "short" ? BodyLong : BodyShort;
70+
71+
return {
72+
normal: ({ children }) =>
73+
withSanitizedBlock(
74+
<BodyComponent
75+
spacing
76+
className={styles.removeSpacingForLast}
77+
size={typoConfig.size}
78+
>
79+
{children}
80+
</BodyComponent>,
81+
),
82+
83+
detail: ({ children }) =>
84+
withSanitizedBlock(<Detail spacing>{children}</Detail>),
85+
ingress: ({ children }) =>
86+
withSanitizedBlock(
87+
<BodyLong size="large" spacing>
88+
{children}
89+
</BodyLong>,
90+
),
91+
h2: ({ children, value }) =>
92+
withSanitizedBlock(
93+
<Heading
94+
className={styles.headingElement}
95+
tabIndex={-1}
96+
id={value?._key}
97+
level="2"
98+
size="large"
99+
data-level="2"
100+
>
101+
{children}
102+
</Heading>,
103+
),
104+
h3: ({ children, value }) =>
105+
withSanitizedBlock(
106+
<Heading
107+
className={styles.headingElement}
108+
spacing
109+
level="3"
110+
size="medium"
111+
tabIndex={-1}
112+
id={value?._key}
113+
data-level="3"
114+
>
115+
{children}
116+
</Heading>,
117+
),
118+
h4: ({ children, value }) =>
119+
withSanitizedBlock(
120+
<Heading
121+
className={styles.headingElement}
122+
spacing
123+
level="4"
124+
size="small"
125+
id={value?._key}
126+
data-level="4"
127+
>
128+
{children}
129+
</Heading>,
130+
),
131+
heading4: ({ children, value }) =>
132+
withSanitizedBlock(
133+
<Heading
134+
className={styles.headingElement}
135+
spacing
136+
level="4"
137+
size="small"
138+
id={value?._key}
139+
data-level="4"
140+
>
141+
{children}
142+
</Heading>,
143+
),
144+
} satisfies Record<string, PortableTextBlockComponent>;
145+
}
146+
147+
function withSanitizedBlock(node: React.ReactElement) {
148+
const { children } = node.props;
149+
const validChildren = Children.toArray(children).filter(Boolean);
150+
151+
if (validChildren.length === 0) {
152+
return null;
153+
}
154+
155+
return node;
156+
}
157+
158+
export { customPortableTextComponents };
159+
export type { CustomPortableTextComponentsProps };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.removeSpacingForLast:last-child {
2+
margin-bottom: 0;
3+
}
4+
5+
.headingElement {
6+
color: var(--ax-text-brand-blue);
7+
scroll-margin-block: var(--ax-space-80);
8+
9+
&[data-level="2"] {
10+
margin-block: var(--ax-space-48) var(--ax-space-16);
11+
12+
&:first-of-type {
13+
margin-top: 0;
14+
}
15+
}
16+
17+
&[data-level="3"] {
18+
margin-block-start: var(--ax-space-32);
19+
}
20+
21+
&[data-level="4"] {
22+
margin-block-start: var(--ax-space-24);
23+
}
24+
25+
&:focus {
26+
outline: none;
27+
}
28+
}

0 commit comments

Comments
 (0)