Skip to content
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

V3-text-block-props #863

Merged
merged 5 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import CustomLink from "src/components/link/CustomLink";
import Text from "src/components/text/Text";
import { LinkType } from "studio/lib/interfaces/navigation";
import { TextBlock } from "studioShared/lib/interfaces/textBlock";

import styles from "./textSection.module.css";
Expand All @@ -12,11 +14,36 @@ export default function TextSection({ section }: TextSectionProps) {
<div className={styles.wrapper}>
<div
className={
styles.content + (section.highlighted ? ` ${styles.highlighted}` : "")
styles.content +
(section.textBlockType === "highlighted"
? ` ${styles.highlighted}`
: "")
}
>
<div className={styles.innerContent}>
<Text>{section.text}</Text>
<div>
{section.sectionTitle && (
<Text className={styles.header} type={"h5"}>
{section.sectionTitle}
</Text>
)}
<Text>{section.text}</Text>
</div>
<div className={styles.link}>
{section.url && (
<CustomLink
size={"small"}
link={{
_key: "read-more",
_type: "link",
linkType: LinkType.External,
linkTitle: "Les mer", //Todo: Add translation
newTab: true,
url: section.url,
}}
/>
)}
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
}

.content {
Expand All @@ -14,8 +15,24 @@
background-color: var(--primary-yellow-warning);
}

.innerContent {
display: flex;
flex-direction: column;
justify-content: space-between;
}

.highlighted .innerContent {
background-color: var(--primary-bg);
border-radius: 1.25rem;
padding: 1rem;
height: fit-content;
}
.header {
margin-bottom: 16px;
}

.link {
margin-top: 2rem;
text-decoration: none;
color: var(--primary-black-darker);
}
3 changes: 3 additions & 0 deletions src/components/text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type TextType =
| "h5"
| "h6"
| "desktopLink"
| "desktopLinkBig"
| "labelSmall"
| "labelLight"
| "labelRegular"
Expand All @@ -32,6 +33,7 @@ const elementMap: { [key in TextType]: keyof JSX.IntrinsicElements } = {
h5: "h5",
h6: "h6",
desktopLink: "p",
desktopLinkBig: "p",
labelSmall: "p",
labelLight: "p",
labelRegular: "p",
Expand All @@ -56,6 +58,7 @@ const classMap: { [key in TextType]?: string } = {
h5: styles.h5,
h6: styles.h6,
desktopLink: styles.desktopLink,
desktopLinkBig: styles.desktopLinkBig,
labelSmall: styles.labelSmall,
labelLight: styles.labelLight,
labelRegular: styles.labelRegular,
Expand Down
16 changes: 15 additions & 1 deletion src/components/text/text.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,14 @@
line-height: 120%; /* 1.8rem */
}

.h5 {
font-size: 1.25rem;
font-style: normal;
font-weight: 400;
line-height: 120%;
}

/* TODO: add font variables */
/* .h5 */
/* .h6 */

.desktopLink {
Expand All @@ -56,6 +62,14 @@
line-height: 110%;
}

.desktopLinkBig {
font-size: 1.25rem;
font-style: normal;
font-weight: 300;
line-height: 120%;
text-decoration-line: underline;
}

.bodyXl {
font-size: 2.125rem;
font-weight: 500;
Expand Down
4 changes: 3 additions & 1 deletion studioShared/lib/interfaces/textBlock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export interface TextBlock {
_key: string;
_type: "textBlock";
sectionTitle?: string;
text: string;
highlighted?: boolean;
url?: string;
textBlockType?: string;
}
4 changes: 3 additions & 1 deletion studioShared/lib/queries/customerCases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ export const CUSTOMER_CASES_QUERY = groq`

export const BASE_SECTIONS_FRAGMENT = groq`
_type == "textBlock" => {
"sectionTitle": ${translatedFieldFragment("sectionTitle")},
"text": ${translatedFieldFragment("text")},
highlighted
url,
textBlockType,
},
_type == "imageBlock" => {
"images": images[] {
Expand Down
2 changes: 1 addition & 1 deletion studioShared/schemas/fields/customerCaseProjectInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const customerCaseProjectInfo = defineField({
],
preview: {
select: {
item: "delivery",
delivery: "delivery",
},
prepare({ delivery }) {
if (!isInternationalizedString(delivery)) {
Expand Down
56 changes: 56 additions & 0 deletions studioShared/schemas/objects/richTextBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { defineField } from "sanity";

import { isInternationalizedRichText } from "studio/lib/interfaces/global";
import { firstTranslation } from "studio/utils/i18n";
import { richTextPreview } from "studio/utils/preview";

const richTextBlock = defineField({
name: "richTextBlock",
title: "Rich Text Block",
type: "object",
fields: [
{
name: "title",
title: "Section Title",
type: "internationalizedArrayString",
},
{
name: "richText",
title: "Rich Text",
type: "internationalizedArrayRichText",
},
{
name: "highlighted",
title: "Highlighted",
type: "boolean",
description: "Display the rich text with a highlight frame",
initialValue: false,
},
],
preview: {
select: {
richText: "richText",
highlighted: "highlighted",
},
prepare({ richText, highlighted }) {
if (!isInternationalizedRichText(richText)) {
throw new TypeError(
`Expected 'richText' to be InternationalizedRichText, was ${typeof richText}`,
);
}
const translatedRichText = firstTranslation(richText);
return {
title:
translatedRichText !== null
? richTextPreview(translatedRichText)
: undefined,
subtitle:
typeof highlighted === "boolean" && highlighted
? "Highlighted"
: undefined,
};
},
},
});

export default richTextBlock;
91 changes: 79 additions & 12 deletions studioShared/schemas/objects/textBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,98 @@ const textBlock = defineField({
title: "Text Block",
type: "object",
fields: [
{
name: "sectionTitle",
title: "Section Title",
type: "internationalizedArrayString",
description:
"Section title is optional, and cannot be more than 50 characters.",
validation: (rule) =>
rule.custom<{ value: string; _type: string; _key: string }[]>(
(value) => {
if (!value) return true;

const invalidItems = value.filter(
(item) =>
typeof item.value === "string" && item.value.length > 50,
);

if (invalidItems.length > 0) {
return invalidItems.map((item) => ({
message: "Title cannot be more than 50 characters long.",
path: [{ _key: item._key }, "value"],
}));
}

return true;
},
),
},
{
name: "text",
title: "Text",
title: "Block text content",
type: "internationalizedArrayText",
description:
"Please type the text content for the block. This field is required, and cannot be more than 300 characters.",
validation: (rule) =>
rule.custom<{ value: string; _type: string; _key: string }[]>(
(value) => {
if (!value || value.length === 0) {
return { message: "This field is required." };
}
const invalidItems = value.filter(
(item) =>
typeof item.value === "string" && item.value.length > 300,
);

if (invalidItems.length > 0) {
return invalidItems.map((item) => ({
message: "Title cannot be more than 50 characters long.",
path: [{ _key: item._key }, "value"],
}));
}
return true;
},
),
},
{
name: "url",
title: "Enter an external link",
type: "url",
description:
"If the text block should include a URL, please enter the full URL, including 'https://'. For example, 'https://www.example.com'.",
validation: (rule) =>
rule.uri({
scheme: ["http", "https"],
allowRelative: false,
}),
},
{
name: "highlighted",
title: "Highlighted",
type: "boolean",
description: "Display the text with a highlight frame",
initialValue: false,
name: "textBlockType",
title: "Text Block Type",
type: "string",
description: "Please choose the style you want for the text box.",
options: {
list: [
{ title: "Normal", value: "normal" },
{ title: "Highlighted", value: "highlighted" },
{ title: "Framed", value: "framed" },
],
layout: "radio",
direction: "vertical",
},
initialValue: "normal",
},
],
preview: {
select: {
text: "text",
highlighted: "highlighted",
textBlockType: "textBlockType",
},
prepare({ text, highlighted }) {
prepare({ text, textBlockType }) {
return {
title: firstTranslation(text) ?? undefined,
subtitle:
typeof highlighted === "boolean" && highlighted
? "Highlighted"
: undefined,
subtitle: textBlockType ? textBlockType : undefined,
};
},
},
Expand Down