Skip to content

Commit

Permalink
Merge branch 'v3' into add-field-translations
Browse files Browse the repository at this point in the history
  • Loading branch information
christinaroise committed Sep 25, 2024
2 parents f5bd6c0 + e2602ab commit 4dde555
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 120 deletions.
3 changes: 3 additions & 0 deletions internationalization/supportedLanguages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ export const supportedLanguages: Language[] = [
];

export const defaultLanguage = supportedLanguages.find((lang) => lang.default);
export function getLanguageById(id: string) {
return supportedLanguages.find((lang) => lang.id === id);
}
4 changes: 2 additions & 2 deletions src/components/buttons/button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
border: 1px solid var(--primary-dark);

&:hover {
background: #085156;
background: var(--primary-darker);
}

&:active {
background: #053235;
background: var(--primary-darker);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/linkButton/linkButton.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@
border: 1px solid var(--primary-dark);

&:hover {
background: #085156;
background: var(--primary-darker);
}

&:active {
background: #053235;
background: var(--primary-darker);
}

&::after {
Expand Down
194 changes: 85 additions & 109 deletions studio/components/LanguageSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { Box, Button, Card, Checkbox, Flex, Text, useTheme } from "@sanity/ui";
import { Box, Button, Card, Checkbox, Flex, useTheme } from "@sanity/ui";
import React from "react";
import { PatchEvent, set } from "sanity";
import { ArrayOfObjectsInputProps, PatchEvent, set } from "sanity";

import {
Language,
supportedLanguages,
} from "internationalization/supportedLanguages";

interface LanguageSelectorProps {
value?: Language[];
onChange: (event: PatchEvent) => void;
}

const colorMap = {
dark: {
selected: "#29356a",
Expand All @@ -23,129 +18,110 @@ const colorMap = {
},
};

const LanguageSelector = ({ value = [], onChange }: LanguageSelectorProps) => {
const LanguageSelector = (props: ArrayOfObjectsInputProps<Language>) => {
const { value = [], onChange } = props;
const theme = useTheme();
const prefersDark = theme.sanity.v2?.color._dark ?? false;
const themeType = prefersDark ? "dark" : "light";
const currentDefaultLanguage: string | null =
value.find((lang) => lang.default)?.id || null;

// Get the currently set default language
const currentDefaultLanguage = value.find((lang) => lang.default)?.id || null;

const handleLanguageSelection = (lang: Language) => {
const isSelected = value.some((item) => item.id === lang.id);
// Prevent deselecting the last remaining language
if (isSelected && value.length === 1) {
console.log("Cannot deselect the last remaining language.");
return; // Exit early if there's only one language selected
}
const getNextDefaultLanguage = (updatedValue: Language[], lang: Language) => {
const indexInSupported = supportedLanguages.findIndex(
(language) => language.id === lang.id,
);
return (
supportedLanguages
.slice(indexInSupported + 1)
.find((language) =>
updatedValue.some((item) => item.id === language.id),
) ||
supportedLanguages.find((language) =>
updatedValue.some((item) => item.id === language.id),
)
);
};

const updatedValue = isSelected
? value.filter((item) => item.id !== lang.id) // Deselect language
: [...value, { ...lang, default: false }]; // Select language
const handleLanguageSelection = (lang: Language, isSelected: boolean) => {
if (isSelected && value.length === 1) return;

const newDefaultLanguage = getNewDefaultLanguage(
updatedValue,
currentDefaultLanguage,
lang,
);
let updatedValue = isSelected
? value.filter((item) => item.id !== lang.id)
: [...value, { ...lang, default: false }];

const finalValue = updatedValue.map((item) => ({
...item,
default: item.id === newDefaultLanguage,
}));
if (isSelected && lang.id === currentDefaultLanguage) {
const nextDefaultLanguage = getNextDefaultLanguage(updatedValue, lang);
updatedValue = updatedValue.map((item) => ({
...item,
default: item.id === (nextDefaultLanguage?.id || null),
}));
}

onChange(PatchEvent.from(set(finalValue)));
onChange(PatchEvent.from(set(updatedValue)));
};

const handleDefaultSetting = (lang: Language) => {
const updatedValue = value.map((item) => ({
...item,
default: item.id === lang.id, // Set selected language as default
default: item.id === lang.id,
}));
onChange(PatchEvent.from(set(updatedValue)));
};

const getBackgroundColor = (lang: Language) => {
const isSelected = value.some((item) => item.id === lang.id);
const theme = prefersDark ? "dark" : "light";

return isSelected ? colorMap[theme].selected : colorMap[theme].default;
};

return (
<Flex direction="column" gap={3}>
{supportedLanguages.map((lang) => (
<Card
key={lang._key}
padding={4}
radius={2}
shadow={1}
style={{
cursor: "pointer",
backgroundColor: getBackgroundColor(lang),
}}
onClick={() => handleLanguageSelection(lang)}
>
<Flex align="center" justify="space-between">
<Flex align="center">
<Checkbox
id={lang.id}
checked={value.some((item) => item.id === lang.id)}
readOnly
/>
<Box flex={1} paddingLeft={3}>
<Text>
<label htmlFor={lang.id}>
{supportedLanguages.map((lang) => {
const isSelected = value.some((item) => item.id === lang.id);
const backgroundColor = isSelected
? colorMap[themeType].selected
: colorMap[themeType].default;

return (
<label htmlFor={lang.id} key={lang.id}>
<Card
padding={4}
radius={2}
shadow={1}
style={{ cursor: "pointer", backgroundColor }}
>
<Flex align="center" justify="space-between">
<Flex align="center">
<Checkbox
id={lang.id}
checked={isSelected}
onClick={() => handleLanguageSelection(lang, isSelected)}
aria-label={`Select ${lang.title}`}
/>
<Box flex={1} paddingLeft={3}>
{lang.icon} {lang.title}
</label>
</Text>
</Box>
</Flex>
{value.some((item) => item.id === lang.id) && (
<Box>
<Button
padding={2}
onClick={(e) => {
e.stopPropagation(); // Prevent triggering card's click handler
handleDefaultSetting(lang);
}}
mode={
currentDefaultLanguage === lang.id ? "default" : "ghost"
}
tone="primary"
>
{currentDefaultLanguage === lang.id
? "Default"
: "Set as Default"}
</Button>
</Box>
)}
</Flex>
</Card>
))}
</Box>
</Flex>
{isSelected && (
<Box>
<Button
padding={2}
onClick={(e) => {
e.stopPropagation();
handleDefaultSetting(lang);
}}
mode={
currentDefaultLanguage === lang.id ? "default" : "ghost"
}
tone="primary"
>
{currentDefaultLanguage === lang.id
? "Default"
: "Set as Default"}
</Button>
</Box>
)}
</Flex>
</Card>
</label>
);
})}
</Flex>
);
};

// Helper function to determine the new default language
const getNewDefaultLanguage = (
updatedLanguages: Language[],
currentDefault: string | null,
deselectedLang: Language,
): string | null => {
if (updatedLanguages.length === 1) {
return updatedLanguages[0].id;
}

if (currentDefault === deselectedLang.id) {
// Find a new default language if the current default is deselected
return (
supportedLanguages.find((lang) =>
updatedLanguages.some((item) => item.id === lang.id),
)?.id || null
);
}

return currentDefault; // Return existing default
};

export default LanguageSelector;
6 changes: 2 additions & 4 deletions studio/schemas/documents/admin/legalDocuments.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineField } from "sanity";

import languageSchemaField from "internationalization/languageSchemaField";
import { supportedLanguages } from "internationalization/supportedLanguages";
import { getLanguageById } from "internationalization/supportedLanguages";
import { richText, title } from "studio/schemas/fields/text";
import { titleSlug } from "studio/schemas/schemaTypes/slug";

Expand All @@ -18,9 +18,7 @@ const legalDocument = defineField({
language: "language",
},
prepare({ title, language }) {
const languageEntry = supportedLanguages.find(
(lang) => lang.id === language,
)?.title;
const languageEntry = getLanguageById(language)?.title;

const languageTitle = languageEntry
? languageEntry
Expand Down
3 changes: 0 additions & 3 deletions studio/schemas/objects/sections/callToAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ export const callToAction = defineField({
validation: (rule) => rule.required(),
},
],
initialValue: {
theme: "primary",
},
preview: {
select: {
title: "basicTitle",
Expand Down

0 comments on commit 4dde555

Please sign in to comment.