Added language selector + better use of components
This commit is contained in:
parent
b634c92142
commit
57399a60dd
@ -3,6 +3,9 @@ import MainPanel from "./Panels/MainPanel";
|
||||
import { useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import { useRouter } from "next/router";
|
||||
import Button from "components/Button";
|
||||
import { prettyLanguage } from "queries/helpers";
|
||||
|
||||
type AppLayoutProps = {
|
||||
subPanel?: React.ReactNode;
|
||||
@ -14,9 +17,11 @@ type AppLayoutProps = {
|
||||
|
||||
export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
const titlePrefix = "Accord’s Library";
|
||||
const router = useRouter();
|
||||
|
||||
const [mainPanelOpen, setMainPanelOpen] = useState(false);
|
||||
const [subPanelOpen, setsubPanelOpen] = useState(false);
|
||||
const [subPanelOpen, setSubPanelOpen] = useState(false);
|
||||
const [languagePanelOpen, setLanguagePanelOpen] = useState(false);
|
||||
const sensibilitySwipe = 1.1;
|
||||
|
||||
const handlers = useSwipeable({
|
||||
@ -25,13 +30,13 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
if (mainPanelOpen) {
|
||||
setMainPanelOpen(false);
|
||||
} else if (props.subPanel && props.contentPanel) {
|
||||
setsubPanelOpen(true);
|
||||
setSubPanelOpen(true);
|
||||
}
|
||||
},
|
||||
onSwipedRight: (SwipeEventData) => {
|
||||
if (SwipeEventData.velocity < sensibilitySwipe) return;
|
||||
if (subPanelOpen) {
|
||||
setsubPanelOpen(false);
|
||||
setSubPanelOpen(false);
|
||||
} else {
|
||||
setMainPanelOpen(true);
|
||||
}
|
||||
@ -74,7 +79,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
<p className="text-2xl font-black font-headers">{props.title}</p>
|
||||
<span
|
||||
className="material-icons mt-[.1em] cursor-pointer"
|
||||
onClick={() => setsubPanelOpen(true)}
|
||||
onClick={() => setSubPanelOpen(true)}
|
||||
>
|
||||
{props.subPanel && !turnSubIntoContent
|
||||
? props.subPanelIcon
|
||||
@ -110,12 +115,12 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
${turnSubIntoContent ? "z-10" : ""}
|
||||
${
|
||||
mainPanelOpen || subPanelOpen
|
||||
? " opacity-50"
|
||||
: "opacity-0 translate-x-full"
|
||||
? "opacity-50"
|
||||
: "opacity-0 pointer-events-none touch-none"
|
||||
}`}
|
||||
onClick={() => {
|
||||
setMainPanelOpen(false);
|
||||
setsubPanelOpen(false);
|
||||
setSubPanelOpen(false);
|
||||
}}
|
||||
></div>
|
||||
|
||||
@ -142,7 +147,48 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
className={`${mainPanelClass} border-r-[1px] border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light bg-paper bg-blend-multiply bg-local bg-[length:10cm]
|
||||
${mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
||||
>
|
||||
<MainPanel langui={props.langui} />
|
||||
<MainPanel
|
||||
langui={props.langui}
|
||||
setLanguagePanelOpen={setLanguagePanelOpen}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Language selection background */}
|
||||
<div
|
||||
className={`fixed bg-dark inset-0 transition-all duration-500 z-20 grid place-content-center ${
|
||||
languagePanelOpen
|
||||
? "bg-opacity-50"
|
||||
: "bg-opacity-0 pointer-events-none touch-none"
|
||||
}`}
|
||||
onClick={() => {
|
||||
setLanguagePanelOpen(false);
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={`p-10 bg-light rounded-lg shadow-2xl shadow-dark grid gap-4 place-items-center transition-transform ${
|
||||
languagePanelOpen ? "scale-100" : "scale-0"
|
||||
}`}
|
||||
>
|
||||
<h2 className="text-2xl">Select a language</h2>
|
||||
<div className="flex flex-wrap flex-row gap-2">
|
||||
{router.locales?.sort().map((locale) => (
|
||||
<>
|
||||
{locale !== "xx" ? (
|
||||
<Button
|
||||
key={locale}
|
||||
active={locale === router.locale}
|
||||
href={router.asPath}
|
||||
locale={locale}
|
||||
>
|
||||
{prettyLanguage(locale)}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -4,19 +4,27 @@ type ButtonProps = {
|
||||
className?: string;
|
||||
href?: string;
|
||||
children: React.ReactChild | React.ReactChild[];
|
||||
active?: boolean;
|
||||
locale?: string;
|
||||
};
|
||||
|
||||
export default function Button(props: ButtonProps): JSX.Element {
|
||||
const button = (
|
||||
<div
|
||||
className={`grid place-content-center place-items-center border-[1px] border-dark text-dark rounded-full cursor-pointer px-4 pt-[0.4rem] pb-[0.5rem] transition-all hover:text-light hover:bg-dark hover:drop-shadow-dark-lg active:bg-black active:drop-shadow-black-lg active:border-black ${props.className}`}
|
||||
className={`grid place-content-center place-items-center border-[1px] border-dark text-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all ${
|
||||
props.className
|
||||
} ${
|
||||
props.active
|
||||
? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed"
|
||||
: "cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-dark-lg active:bg-black active:drop-shadow-black-lg active:border-black"
|
||||
}`}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
||||
const result = props.href ? (
|
||||
<Link href={props.href} passHref>
|
||||
<Link href={props.href} locale={props.locale} passHref>
|
||||
{button}
|
||||
</Link>
|
||||
) : (
|
||||
|
@ -6,11 +6,7 @@ type ChipProps = {
|
||||
export default function Chip(props: ChipProps): JSX.Element {
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"grid place-content-center place-items-center text-xs pb-[0.14rem] px-1.5 border-[1px] rounded-full opacity-70" +
|
||||
" " +
|
||||
props.className
|
||||
}
|
||||
className={`grid place-content-center place-items-center text-xs pb-[0.14rem] px-1.5 border-[1px] rounded-full opacity-70 ${props.className}`}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
|
16
src/components/InsetBox.tsx
Normal file
16
src/components/InsetBox.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
type InsetBoxProps = {
|
||||
className?: string;
|
||||
children: React.ReactChild | React.ReactChild[];
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export default function InsetBox(props: InsetBoxProps): JSX.Element {
|
||||
return (
|
||||
<div
|
||||
id={props.id}
|
||||
className={`w-full shadow-inner-sm shadow-dark bg-mid rounded-xl p-8 ${props.className}`}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -15,7 +15,7 @@ export default function NavOption(props: NavOptionProps): JSX.Element {
|
||||
const divActive = "bg-mid shadow-inner-sm shadow-dark";
|
||||
const border =
|
||||
"outline outline-mid outline-2 outline-offset-[-2px] hover:outline-[transparent]";
|
||||
const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid hover:shadow-inner-sm hover:shadow-dark active:shadow-inner active:shadow-dark transition-all ${
|
||||
const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid hover:shadow-inner-sm hover:shadow-dark hover:active:shadow-inner hover:active:shadow-dark transition-all ${
|
||||
props.border ? border : ""
|
||||
} ${isActive ? divActive : ""}`;
|
||||
|
||||
|
@ -9,6 +9,7 @@ import Markdown from "markdown-to-jsx";
|
||||
|
||||
type MainPanelProps = {
|
||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||
setLanguagePanelOpen: Function;
|
||||
};
|
||||
|
||||
export default function MainPanel(props: MainPanelProps): JSX.Element {
|
||||
@ -29,7 +30,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
<div className="relative mt-5">
|
||||
<div className="relative mt-5" onClick={() => props.setLanguagePanelOpen(true)}>
|
||||
{router.locale ? (
|
||||
<Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5">
|
||||
{router.locale.toUpperCase()}
|
||||
|
@ -82,6 +82,7 @@ query getEras($language_code: String) {
|
||||
ending_year
|
||||
title(filters: { language: { code: { eq: $language_code } } }) {
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,119 +125,118 @@ query getChronologyItems($language_code: String) {
|
||||
}
|
||||
|
||||
query getLibraryItemsPreview($language_code: String) {
|
||||
libraryItems(
|
||||
filters: { root_item: { eq: true } }
|
||||
pagination: { limit: -1 }
|
||||
sort: ["title:asc", "subtitle:asc"]
|
||||
) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
title
|
||||
subtitle
|
||||
slug
|
||||
thumbnail {
|
||||
data {
|
||||
attributes {
|
||||
name
|
||||
alternativeText
|
||||
caption
|
||||
width
|
||||
height
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
release_date {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
price {
|
||||
amount
|
||||
currency {
|
||||
data {
|
||||
attributes {
|
||||
symbol
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
metadata {
|
||||
__typename
|
||||
... on ComponentMetadataBooks {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataGame {
|
||||
platform {
|
||||
data {
|
||||
attributes {
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataVideo {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataAudio {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataOther {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
libraryItems(
|
||||
filters: { root_item: { eq: true } }
|
||||
pagination: { limit: -1 }
|
||||
sort: ["title:asc", "subtitle:asc"]
|
||||
) {
|
||||
data {
|
||||
id
|
||||
attributes {
|
||||
title
|
||||
subtitle
|
||||
slug
|
||||
thumbnail {
|
||||
data {
|
||||
attributes {
|
||||
name
|
||||
alternativeText
|
||||
caption
|
||||
width
|
||||
height
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
release_date {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
price {
|
||||
amount
|
||||
currency {
|
||||
data {
|
||||
attributes {
|
||||
symbol
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
metadata {
|
||||
__typename
|
||||
... on ComponentMetadataBooks {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataGame {
|
||||
platform {
|
||||
data {
|
||||
attributes {
|
||||
short
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataVideo {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataAudio {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataOther {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
slug
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
query getLibraryItemsSlugs {
|
||||
libraryItems(pagination: { limit: -1 }) {
|
||||
data {
|
||||
|
@ -165,6 +165,7 @@ export type GetErasQuery = {
|
||||
title: Array<{
|
||||
__typename: "ComponentTranslationsChronologyEra";
|
||||
title: string;
|
||||
description: string;
|
||||
}>;
|
||||
};
|
||||
}>;
|
||||
|
@ -32,6 +32,7 @@ import Button from "components/Button";
|
||||
import HorizontalLine from "components/HorizontalLine";
|
||||
import AppLayout from "components/AppLayout";
|
||||
import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
|
||||
import InsetBox from "components/InsetBox";
|
||||
|
||||
type LibrarySlugProps = {
|
||||
libraryItem: GetLibraryItemQuery;
|
||||
@ -124,10 +125,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="summary"
|
||||
className="bg-mid w-full grid place-items-center p-8 rounded-2xl shadow-inner-sm shadow-dark"
|
||||
>
|
||||
<InsetBox id="summary" className="grid place-items-center">
|
||||
<div className="w-[clamp(0px,100%,42rem)] grid place-items-center gap-8">
|
||||
{item.subitem_of.data.length > 0 ? (
|
||||
<div className="grid place-items-center">
|
||||
@ -159,7 +157,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</InsetBox>
|
||||
|
||||
{item.gallery.data.length > 0 ? (
|
||||
<div id="gallery" className="grid place-items-center gap-8 w-full">
|
||||
@ -188,9 +186,9 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||
""
|
||||
)}
|
||||
|
||||
<div
|
||||
<InsetBox
|
||||
id="details"
|
||||
className="bg-mid w-full grid place-items-center p-8 rounded-2xl text-left shadow-inner-sm shadow-dark"
|
||||
className="grid place-items-center"
|
||||
>
|
||||
<div className="w-[clamp(0px,100%,42rem)] grid place-items gap-8">
|
||||
<h2 className="text-2xl text-center">
|
||||
@ -345,7 +343,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</InsetBox>
|
||||
|
||||
{item.subitems.data.length > 0 ? (
|
||||
item.metadata.length > 0 &&
|
||||
|
@ -16,6 +16,8 @@ import NavOption from "components/PanelComponents/NavOption";
|
||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
||||
import HorizontalLine from "components/HorizontalLine";
|
||||
import AppLayout from "components/AppLayout";
|
||||
import { prettySlug } from "queries/helpers";
|
||||
import InsetBox from "components/InsetBox";
|
||||
|
||||
interface DataChronologyProps {
|
||||
chronologyItems: GetChronologyItemsQuery;
|
||||
@ -27,20 +29,39 @@ export default function DataChronology(
|
||||
props: DataChronologyProps
|
||||
): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const chronologyItems = props.chronologyItems.chronologyItems;
|
||||
const chronologyEras = props.chronologyEras.chronologyEras;
|
||||
|
||||
// Group by year the Chronology items
|
||||
let chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][] =
|
||||
let chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][][] =
|
||||
[];
|
||||
|
||||
if (props.chronologyItems.chronologyItems) {
|
||||
props.chronologyItems.chronologyItems.data.map((item) => {
|
||||
if (!chronologyItemYearGroups.hasOwnProperty(item.attributes.year)) {
|
||||
chronologyItemYearGroups[item.attributes.year] = [item];
|
||||
} else {
|
||||
chronologyItemYearGroups[item.attributes.year].push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
chronologyEras.data.map((era) => {
|
||||
chronologyItemYearGroups.push([]);
|
||||
});
|
||||
|
||||
let currentChronologyEraIndex = 0;
|
||||
chronologyItems.data.map((item) => {
|
||||
if (
|
||||
item.attributes.year >
|
||||
chronologyEras.data[currentChronologyEraIndex].attributes.ending_year
|
||||
) {
|
||||
currentChronologyEraIndex++;
|
||||
}
|
||||
if (
|
||||
!chronologyItemYearGroups[currentChronologyEraIndex].hasOwnProperty(
|
||||
item.attributes.year
|
||||
)
|
||||
) {
|
||||
chronologyItemYearGroups[currentChronologyEraIndex][
|
||||
item.attributes.year
|
||||
] = [item];
|
||||
} else {
|
||||
chronologyItemYearGroups[currentChronologyEraIndex][
|
||||
item.attributes.year
|
||||
].push(item);
|
||||
}
|
||||
});
|
||||
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
@ -51,7 +72,7 @@ export default function DataChronology(
|
||||
<NavOption
|
||||
key={era.id}
|
||||
url={"#" + era.attributes.slug}
|
||||
title={era.attributes.title[0] ? era.attributes.title[0].title : ""}
|
||||
title={era.attributes.title.length > 0 ? era.attributes.title[0].title : prettySlug(era.attributes.slug)}
|
||||
subtitle={
|
||||
era.attributes.starting_year + " → " + era.attributes.ending_year
|
||||
}
|
||||
@ -63,17 +84,32 @@ export default function DataChronology(
|
||||
|
||||
const contentPanel = (
|
||||
<ContentPanel>
|
||||
{chronologyItemYearGroups.map((items, index: number) => {
|
||||
if (items && items[0].attributes.year) {
|
||||
return (
|
||||
{chronologyItemYearGroups.map((era, eraIndex) => (
|
||||
<>
|
||||
<InsetBox
|
||||
id={chronologyEras.data[eraIndex].attributes.slug}
|
||||
className="grid text-center my-8 gap-4"
|
||||
>
|
||||
<h2 className="text-2xl">
|
||||
{chronologyEras.data[eraIndex].attributes.title.length > 0
|
||||
? chronologyEras.data[eraIndex].attributes.title[0].title
|
||||
: prettySlug(chronologyEras.data[eraIndex].attributes.slug)}
|
||||
</h2>
|
||||
<p className="whitespace-pre-line ">
|
||||
{chronologyEras.data[eraIndex].attributes.title.length > 0
|
||||
? chronologyEras.data[eraIndex].attributes.title[0].description
|
||||
: ""}
|
||||
</p>
|
||||
</InsetBox>
|
||||
{era.map((items, index) => (
|
||||
<ChronologyYearComponent
|
||||
key={index}
|
||||
key={`${eraIndex}-${index}`}
|
||||
year={items[0].attributes.year}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
))}
|
||||
</>
|
||||
))}
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
|
@ -51,7 +51,7 @@ export function prettyinlineTitle(
|
||||
|
||||
export function prettyItemType(
|
||||
metadata: {
|
||||
__typename: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number]["__typename"]
|
||||
__typename: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number]["__typename"];
|
||||
},
|
||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]
|
||||
): string {
|
||||
@ -73,7 +73,7 @@ export function prettyItemType(
|
||||
}
|
||||
|
||||
export function prettyItemSubType(
|
||||
metadata: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number],
|
||||
metadata: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number]
|
||||
): string {
|
||||
switch (metadata.__typename) {
|
||||
case "ComponentMetadataAudio":
|
||||
@ -92,6 +92,25 @@ export function prettyItemSubType(
|
||||
}
|
||||
}
|
||||
|
||||
export function prettyLanguage(code: string): string {
|
||||
switch (code) {
|
||||
case "en":
|
||||
return "English";
|
||||
case "es":
|
||||
return "Español";
|
||||
case "fr":
|
||||
return "Français";
|
||||
case "ja":
|
||||
return "日本語";
|
||||
case "en":
|
||||
return "English";
|
||||
case "xx":
|
||||
return "██";
|
||||
default:
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
export function capitalizeString(string: string): string {
|
||||
function capitalizeWord(word: string): string {
|
||||
return word.charAt(0).toUpperCase() + word.substring(1);
|
||||
|
@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
* {
|
||||
@apply box-border font-body font-medium scroll-smooth;
|
||||
@apply box-border font-body font-medium scroll-smooth scroll-m-8;
|
||||
}
|
||||
|
||||
h1,
|
||||
@ -25,10 +25,6 @@
|
||||
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark;
|
||||
}
|
||||
|
||||
*:target {
|
||||
@apply scroll-mt-4;
|
||||
}
|
||||
|
||||
*::selection {
|
||||
@apply bg-dark text-light;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ module.exports = {
|
||||
".drop-shadow-dark-2xl": {
|
||||
filter: "drop-shadow(0 25px 25px rgb(156 102 68 / 0.8))",
|
||||
},
|
||||
|
||||
|
||||
".drop-shadow-black-lg": {
|
||||
filter:
|
||||
"drop-shadow(0 10px 8px rgb(27 24 17 / 0.2)) drop-shadow(0 4px 3px rgb(27 24 17 / 0.4))",
|
||||
|
Loading…
x
Reference in New Issue
Block a user