diff --git a/README.md b/README.md index 25269cb..8d6b9e9 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,11 @@ - Support for Arbitrary React Components and Component Props! - Autogenerated multi-level table of content and anchor links for the different headers - Styling: [Tailwind CSS](https://tailwindcss.com/) - - Manually added support for scrollbar styling + - Manually added support for scrollbar styling to Tailwind CSS - Support for [Material Icons](https://fonts.google.com/icons) - Support for creating any arbitrary theming mode by swapping CSS variables - - Support for many screen sizes and resolutions + - Support for Container Queries (media queries at the element level) + - The website has a three-column layout, which turns into one-column + 2 toggleable side-menus if the screen is too narrow. - State Management: [React Context](https://reactjs.org/docs/context.html) - Persistent app state using LocalStorage - Accessibility @@ -56,7 +57,7 @@ - Performances are great, and possibility to deploy the app using a CDN - On-Demand ISR to continuously update the website when new content is added or existing content is modified/deleted - SEO - - Good defaults for the metadate and OpenGraph properties + - Good defaults for the metadata and OpenGraph properties - Each page can provide the thumbnail, title, description to be used - Automatic generation of the sitemap using [next-sitemap](https://www.npmjs.com/package/next-sitemap) - Data quality testing @@ -105,6 +106,6 @@ Run in dev mode: OR build and run in production mode ```bash -./run_accords_build.sh +npm run build ./run_accords_prod.sh ``` diff --git a/design.config.js b/design.config.js index 7451beb..6bbc07e 100644 --- a/design.config.js +++ b/design.config.js @@ -17,12 +17,6 @@ const colors = { }, }; -const breaks = { - thin: { raw: "(max-width: 25rem)" }, - mobile: { raw: "(max-width: 60rem)" }, - desktop: { raw: "(min-width: 60rem)" }, -}; - const fonts = { openDyslexic: "OpenDyslexic", vollkorn: "Vollkorn", @@ -43,9 +37,16 @@ const fontFamilies = { }, }; +const layout = { + // all values in rem + mainMenuReduced: 6, + mainMenu: 20, + subMenu: 20, +}; + module.exports = { colors, - breaks, + layout, fonts, fontFamilies, }; diff --git a/package-lock.json b/package-lock.json index 175fcbd..b3a1179 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "@graphql-codegen/typescript": "2.7.3", "@graphql-codegen/typescript-graphql-request": "^4.5.3", "@graphql-codegen/typescript-operations": "^2.5.3", - "@types/node": "18.7.8", + "@types/node": "18.7.9", "@types/nodemailer": "^6.4.5", "@types/react": "18.0.17", "@types/react-dom": "^18.0.6", @@ -46,7 +46,7 @@ "eslint-config-next": "12.2.5", "eslint-plugin-import": "^2.26.0", "graphql": "^16.6.0", - "next-sitemap": "^3.1.20", + "next-sitemap": "^3.1.21", "prettier": "^2.7.1", "prettier-plugin-tailwindcss": "^0.1.13", "tailwindcss": "^3.1.8", @@ -2411,9 +2411,9 @@ } }, "node_modules/@types/node": { - "version": "18.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.8.tgz", - "integrity": "sha512-/YP55EMK2341JkODUb8DM9O0x1SIz2aBvyF33Uf1c76St3VpsMXEIW0nxuKkq/5cxnbz0RD9cfwNZHEAZQD3ag==", + "version": "18.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.9.tgz", + "integrity": "sha512-0N5Y1XAdcl865nDdjbO0m3T6FdmQ4ijE89/urOHLREyTXbpMWbSafx9y7XIsgWGtwUP2iYTinLyyW3FatAxBLQ==", "dev": true }, "node_modules/@types/nodemailer": { @@ -6287,9 +6287,9 @@ } }, "node_modules/next-sitemap": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-3.1.20.tgz", - "integrity": "sha512-ugcSQpAtwc9fk7fsr5to0yrlA/RjY0kw2wHOUqcrRXnZDwFfBwGnEVvaYbI7C4ZlhvxjJTA3G15QMpvpmvPquw==", + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-3.1.21.tgz", + "integrity": "sha512-8upGCtI91FvjNBpeKDZzrzRBlY4BH6qjG7dMe89sdBzJ9B++PVLTzRPlpLHJYOEPukBROsxi2zVuAvePBtsrdw==", "dev": true, "funding": [ { @@ -10334,9 +10334,9 @@ } }, "@types/node": { - "version": "18.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.8.tgz", - "integrity": "sha512-/YP55EMK2341JkODUb8DM9O0x1SIz2aBvyF33Uf1c76St3VpsMXEIW0nxuKkq/5cxnbz0RD9cfwNZHEAZQD3ag==", + "version": "18.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.9.tgz", + "integrity": "sha512-0N5Y1XAdcl865nDdjbO0m3T6FdmQ4ijE89/urOHLREyTXbpMWbSafx9y7XIsgWGtwUP2iYTinLyyW3FatAxBLQ==", "dev": true }, "@types/nodemailer": { @@ -13263,9 +13263,9 @@ } }, "next-sitemap": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-3.1.20.tgz", - "integrity": "sha512-ugcSQpAtwc9fk7fsr5to0yrlA/RjY0kw2wHOUqcrRXnZDwFfBwGnEVvaYbI7C4ZlhvxjJTA3G15QMpvpmvPquw==", + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-3.1.21.tgz", + "integrity": "sha512-8upGCtI91FvjNBpeKDZzrzRBlY4BH6qjG7dMe89sdBzJ9B++PVLTzRPlpLHJYOEPukBROsxi2zVuAvePBtsrdw==", "dev": true, "requires": { "@corex/deepmerge": "^4.0.29", diff --git a/package.json b/package.json index 274315b..92ec690 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@graphql-codegen/typescript": "2.7.3", "@graphql-codegen/typescript-graphql-request": "^4.5.3", "@graphql-codegen/typescript-operations": "^2.5.3", - "@types/node": "18.7.8", + "@types/node": "18.7.9", "@types/nodemailer": "^6.4.5", "@types/react": "18.0.17", "@types/react-dom": "^18.0.6", @@ -56,7 +56,7 @@ "eslint-config-next": "12.2.5", "eslint-plugin-import": "^2.26.0", "graphql": "^16.6.0", - "next-sitemap": "^3.1.20", + "next-sitemap": "^3.1.21", "prettier": "^2.7.1", "prettier-plugin-tailwindcss": "^0.1.13", "tailwindcss": "^3.1.8", diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index ce1cbda..97cbb0a 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -4,6 +4,7 @@ import { useEffect, useLayoutEffect, useMemo, useState } from "react"; import { useSwipeable } from "react-swipeable"; import UAParser from "ua-parser-js"; import { useBoolean, useIsClient } from "usehooks-ts"; +import { layout } from "../../design.config"; import { Ico, Icon } from "./Ico"; import { ButtonGroup } from "./Inputs/ButtonGroup"; import { OrderableList } from "./Inputs/OrderableList"; @@ -12,7 +13,6 @@ import { TextInput } from "./Inputs/TextInput"; import { MainPanel } from "./Panels/MainPanel"; import { Popup } from "./Popup"; import { AnchorIds } from "hooks/useScrollTopOnChange"; -import { useMediaMobile } from "hooks/useMediaQuery"; import { filterHasAttributes, isDefined, @@ -27,6 +27,11 @@ import { useAppLayout } from "contexts/AppLayoutContext"; import { Button } from "components/Inputs/Button"; import { OpenGraph, TITLE_PREFIX, TITLE_SEPARATOR } from "helpers/openGraph"; import { getDefaultPreferredLanguages } from "helpers/locales"; +import { + useIs1ColumnLayout, + useIsScreenAtLeast, +} from "hooks/useContainerQuery"; +import { useOnResize } from "hooks/useOnResize"; /* * ╭─────────────╮ @@ -88,10 +93,18 @@ export const AppLayout = ({ setSubPanelOpen, toggleMainPanelOpen, toggleSubPanelOpen, + setScreenWidth, + setContentPanelWidth, + setSubPanelWidth, } = useAppLayout(); const router = useRouter(); - const isMobile = useMediaMobile(); + const is1ColumnLayout = useIs1ColumnLayout(); + const isScreenAtLeastXs = useIsScreenAtLeast("xs"); + + useOnResize(AnchorIds.Body, (width) => setScreenWidth(width)); + useOnResize(AnchorIds.ContentPanel, (width) => setContentPanelWidth(width)); + useOnResize(AnchorIds.SubPanel, (width) => setSubPanelWidth(width)); useEffect(() => { router.events.on("routeChangeStart", () => { @@ -178,18 +191,6 @@ export const AppLayout = ({ setPreferredLanguages, ]); - const gridCol = useMemo(() => { - if (isDefined(subPanel)) { - if (mainPanelReduced) { - return "grid-cols-[6rem_20rem_1fr]"; - } - return "grid-cols-[20rem_20rem_1fr]"; - } else if (mainPanelReduced) { - return "grid-cols-[6rem_0px_1fr]"; - } - return "grid-cols-[20rem_0px_1fr]"; - }, [mainPanelReduced, subPanel]); - const isClient = useIsClient(); const { value: hasDisgardSafariWarning, setTrue: disgardSafariWarning } = useBoolean(false); @@ -212,12 +213,22 @@ export const AppLayout = ({ >
{compProps.children}
@@ -301,12 +318,13 @@ interface HeaderProps { } const Header = ({ level, title, slug, langui }: HeaderProps): JSX.Element => { + const isHoverable = useDeviceSupportsHover(); const innerComponent = useMemo( () => ( <> -{description}
}+
+
+
+
{langui.no_results_message} {langui.no_results_message} {selectedTranslation?.definition} {langui.source}: {channel?.subscribers.toLocaleString()} subscribers
@@ -139,9 +135,9 @@ const Video = ({ langui, video, ...otherProps }: Props): JSX.Element => {
icon={Icon.ThumbUp}
className="mr-1 translate-y-[.15em] !text-base"
/>
- {isMobile
- ? prettyShortenNumber(video.likes)
- : video.likes.toLocaleString()}
+ {isContentPanelAtLeast4xl
+ ? video.likes.toLocaleString()
+ : prettyShortenNumber(video.likes)}
@@ -304,7 +318,7 @@ export const PreviewFolder = ({
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-export const TranslatedPreviewFolder = ({
+const TranslatedPreviewFolder = ({
translations,
fallback,
...otherProps
diff --git a/src/pages/dev/editor.tsx b/src/pages/dev/editor.tsx
index fcb418d..bf65908 100644
--- a/src/pages/dev/editor.tsx
+++ b/src/pages/dev/editor.tsx
@@ -210,7 +210,7 @@ const Editor = ({ langui, ...otherProps }: Props): JSX.Element => {
target.select();
event.preventDefault();
}}
- className="h-[50vh] w-[50vw] mobile:w-[75vw]"
+ className="h-[50vh] w-[50vw]"
/>
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index b87b32b..a0e9e87 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -19,7 +19,7 @@ const Home = ({ langui, ...otherProps }: PostStaticProps): JSX.Element => (
{langui.width}: {langui.height}: {langui.thickness}: {rangeStart}
+ {langui.categories}
+
+ {langui.tags}
+
+ {langui.summary}
+ {selectedTranslation.summary}
- {langui.categories}
-
- {langui.tags}
-
- {langui.summary}
- {selectedTranslation.summary}
@@ -193,7 +199,11 @@ const Wiki = ({ langui, pages, ...otherProps }: Props): JSX.Element => {
/>
)}
langui={langui}
- className="grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))]"
+ className={cIf(
+ isContentPanelAtLeast4xl,
+ "grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] gap-x-6 gap-y-8",
+ "grid-cols-2 gap-x-3 gap-y-5"
+ )}
searchingTerm={searchName}
searchingBy={(item) =>
filterDefined(item.attributes.translations)
@@ -210,7 +220,14 @@ const Wiki = ({ langui, pages, ...otherProps }: Props): JSX.Element => {
/>
),
- [groupingFunction, keepInfoVisible, langui, pages, searchName]
+ [
+ groupingFunction,
+ keepInfoVisible,
+ langui,
+ pages,
+ searchName,
+ isContentPanelAtLeast4xl,
+ ]
);
return (
diff --git a/src/tailwind.css b/src/tailwind.css
index 1a69c12..f59a309 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -35,7 +35,7 @@ mark {
}
*::-webkit-scrollbar {
- @apply w-3 mobile:w-0;
+ @apply w-3;
}
*::-webkit-scrollbar-track {
diff --git a/tailwind.config.js b/tailwind.config.js
index 83ddbf6..5fd366e 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,5 +1,5 @@
const plugin = require("tailwindcss/plugin");
-const { breaks, colors, fonts, fontFamilies } = require("./design.config.js");
+const { colors, fonts, fontFamilies } = require("./design.config.js");
const rgb = (color) => [color.r, color.g, color.b].join(" ");
@@ -23,9 +23,6 @@ module.exports = {
...fonts,
},
screens: {
- desktop: breaks.desktop,
- mobile: breaks.mobile,
- thin: breaks.thin,
hoverable: { raw: "(hover: hover)" },
notHoverable: { raw: "(hover: none)" },
},
{openGraph.title}
- {openGraph.title}
- {channel?.title}
- Accord’s Library
diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx
index b27d58f..f451024 100644
--- a/src/pages/library/[slug]/index.tsx
+++ b/src/pages/library/[slug]/index.tsx
@@ -10,10 +10,7 @@ import { Switch } from "components/Inputs/Switch";
import { InsetBox } from "components/InsetBox";
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
import { NavOption } from "components/PanelComponents/NavOption";
-import {
- ReturnButton,
- ReturnButtonType,
-} from "components/PanelComponents/ReturnButton";
+import { ReturnButton } from "components/PanelComponents/ReturnButton";
import {
ContentPanel,
ContentPanelWidthSizes,
@@ -49,7 +46,7 @@ import {
import { useLightBox } from "hooks/useLightBox";
import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
import { isUntangibleGroupItem } from "helpers/libraryItem";
-import { useMediaHoverable } from "hooks/useMediaQuery";
+import { useDeviceSupportsHover } from "hooks/useMediaQuery";
import { WithLabel } from "components/Inputs/WithLabel";
import { Ico, Icon } from "components/Ico";
import { cJoin, cIf } from "helpers/className";
@@ -58,6 +55,7 @@ import { getOpenGraph } from "helpers/openGraph";
import { getDescription } from "helpers/description";
import { useIntersectionList } from "hooks/useIntersectionList";
import { HorizontalLine } from "components/HorizontalLine";
+import { useIsContentPanelNoMoreThan } from "hooks/useContainerQuery";
/*
* ╭─────────────╮
@@ -97,14 +95,15 @@ const LibrarySlug = ({
...otherProps
}: Props): JSX.Element => {
const { currency } = useAppLayout();
- const hoverable = useMediaHoverable();
+ const isContentPanelNoMoreThan3xl = useIsContentPanelNoMoreThan("3xl");
+ const isContentPanelNoMoreThanSm = useIsContentPanelNoMoreThan("sm");
+ const hoverable = useDeviceSupportsHover();
const router = useRouter();
const [openLightBox, LightBox] = useLightBox();
const { value: keepInfoVisible, toggle: toggleKeepInfoVisible } =
useBoolean(false);
useScrollTopOnChange(AnchorIds.ContentPanel, [item]);
-
const currentIntersection = useIntersectionList(intersectionIds);
const isVariantSet = useMemo(
@@ -130,7 +129,7 @@ const LibrarySlug = ({
href="/library/"
title={langui.library}
langui={langui}
- displayOn={ReturnButtonType.Desktop}
+ displayOnlyOn="3ColumnsLayout"
/>
{langui.details}
{langui.size}
{langui.type_information}
+ {selectedTranslation
+ ? prettyInlineTitle(
+ selectedTranslation.pre_title,
+ selectedTranslation.title,
+ selectedTranslation.subtitle
+ )
+ : content
+ ? prettySlug(content.slug, parentSlug)
+ : prettySlug(slug, parentSlug)}
+
+