Precommit, updated README
This commit is contained in:
parent
fe24a77d6e
commit
42821a7490
20
README.md
20
README.md
|
@ -25,20 +25,20 @@
|
||||||
#### [Front](https://github.com/Accords-Library/accords-library.com) (this repository)
|
#### [Front](https://github.com/Accords-Library/accords-library.com) (this repository)
|
||||||
|
|
||||||
- Language: [TypeScript](https://www.typescriptlang.org/)
|
- Language: [TypeScript](https://www.typescriptlang.org/)
|
||||||
- Framework: [Next.js](https://nextjs.org/) (React)
|
- Framework: [Next.js 12](https://nextjs.org/) (React 18)
|
||||||
- Queries: [GraphQL Code Generator](https://www.graphql-code-generator.com/)
|
- Queries: [GraphQL Code Generator](https://www.graphql-code-generator.com/)
|
||||||
- Fetch the GraphQL schema from the GraphQL back-end endpoint
|
- Fetch the GraphQL schema from the GraphQL back-end endpoint
|
||||||
- Read the operations and fragments stored as graphql files in the `src/graphql` folder
|
- Read the operations and fragments stored as graphql files in the `src/graphql` folder
|
||||||
- Automatically generates a typesafe ready to use SDK using [graphql-request](https://www.npmjs.com/package/graphql-request) as the GraphQL client
|
- Automatically generates a typesafe ready to use SDK using [graphql-request](https://www.npmjs.com/package/graphql-request) as the GraphQL client
|
||||||
- Markdown: [markdown-to-jsx](https://www.npmjs.com/package/markdown-to-jsx)
|
- Markdown: [markdown-to-jsx](https://www.npmjs.com/package/markdown-to-jsx)
|
||||||
- Support for Arbitrary React Components and Component Props!
|
- Support for arbitrary React Components and Component Props!
|
||||||
- Autogenerated multi-level table of content and anchor links for the different headers
|
- Autogenerated multi-level table of content and anchor links for the different headers
|
||||||
- Styling: [Tailwind CSS](https://tailwindcss.com/)
|
- Styling: [Tailwind CSS](https://tailwindcss.com/)
|
||||||
- Support for [Material Icons](https://fonts.google.com/icons)
|
- Support for [Material Icons](https://fonts.google.com/icons)
|
||||||
- Support for creating any arbitrary theming mode by swapping CSS variables
|
- Support for creating any arbitrary theming mode by swapping CSS variables
|
||||||
- Support for Container Queries (media queries at the element level)
|
- 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.
|
- The website has a three-column layout, which turns into one-column + 2 toggleable side-menus if the screen is too narrow.
|
||||||
- Show out the Design System Showcase [here](https://accords-library.com/dev/showcase/design-system)
|
- Check out our [Design System Showcase](https://accords-library.com/dev/showcase/design-system)
|
||||||
- State Management: [React Context](https://reactjs.org/docs/context.html)
|
- State Management: [React Context](https://reactjs.org/docs/context.html)
|
||||||
- Persistent app state using LocalStorage and SessionStorage
|
- Persistent app state using LocalStorage and SessionStorage
|
||||||
- Accessibility
|
- Accessibility
|
||||||
|
@ -52,18 +52,28 @@
|
||||||
- Main and fallback languages can be ordered manually by the user
|
- Main and fallback languages can be ordered manually by the user
|
||||||
- At the content level, the user can know which language is available
|
- At the content level, the user can know which language is available
|
||||||
- Furthermore, the user can temporary select another language then the one that was automatically selected
|
- Furthermore, the user can temporary select another language then the one that was automatically selected
|
||||||
- SSG + ISR (Static Site Generation + Incremental Static Regeneration):
|
- SSG + ISR (Static Site Generation + Incremental Static Regeneration)
|
||||||
- The website is built before running in production
|
- The website is built before running in production
|
||||||
- Performances are great, and possibility to deploy the app on a CDN
|
- Performances are great, and possibility to deploy the app on a CDN
|
||||||
- On-Demand ISR to continuously update the website when new content is added or existing content is modified/deleted
|
- On-Demand ISR to continuously update the website when new content is added or existing content is modified/deleted
|
||||||
|
- UI localizations are downloaded separetely into the `public/local-data` to avoid fetching the same static props for every page.
|
||||||
- SEO
|
- SEO
|
||||||
- Good defaults for the metadata and OpenGraph properties
|
- Good defaults for the metadata and OpenGraph properties
|
||||||
- Each page can provide the thumbnail, title, description to be used
|
- Each page can provide a custom thumbnail, title, description to be used
|
||||||
- Automatic generation of the sitemap using [next-sitemap](https://www.npmjs.com/package/next-sitemap)
|
- Automatic generation of the sitemap using [next-sitemap](https://www.npmjs.com/package/next-sitemap)
|
||||||
- Data quality testing
|
- Data quality testing
|
||||||
- Data from the CMS is subject to a battery of tests (about 20 warning types and 40 error types) at build time
|
- Data from the CMS is subject to a battery of tests (about 20 warning types and 40 error types) at build time
|
||||||
- Each warning/error comes with a front-end link to the incriminating element, as well as a link to the CMS to fix it
|
- Each warning/error comes with a front-end link to the incriminating element, as well as a link to the CMS to fix it
|
||||||
- Check for completeness, conformity, and integrity
|
- Check for completeness, conformity, and integrity
|
||||||
|
- Code quality and style
|
||||||
|
- React Strict Mode
|
||||||
|
- [Eslint](https://www.npmjs.com/package/eslint) with [eslint-plugin-import](https://www.npmjs.com/package/eslint-plugin-import), [typescript-eslint](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin)
|
||||||
|
- [Prettier](https://www.npmjs.com/package/prettier) with [prettier-plugin-tailwindcss](https://www.npmjs.com/package/prettier-plugin-tailwindcss)
|
||||||
|
- [ts-unused-exports](https://www.npmjs.com/package/ts-unused-exports) to find unused exported functions/constants...
|
||||||
|
|
||||||
|
- Other
|
||||||
|
- Custom book reader based on [Okuma-Reader](https://github.com/DrMint/Okuma-Reader)
|
||||||
|
- Custom lightbox using [react-zoom-pan-pinch](https://www.npmjs.com/package/react-zoom-pan-pinch)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ export const AppLayout = ({
|
||||||
<div
|
<div
|
||||||
id={Ids.ContentPanel}
|
id={Ids.ContentPanel}
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
"texture-paper-dots bg-light [grid-area:content]",
|
"bg-light texture-paper-dots [grid-area:content]",
|
||||||
cIf(contentPanelScroolbar, "overflow-y-scroll")
|
cIf(contentPanelScroolbar, "overflow-y-scroll")
|
||||||
)}>
|
)}>
|
||||||
{isDefined(contentPanel) ? (
|
{isDefined(contentPanel) ? (
|
||||||
|
@ -167,8 +167,8 @@ export const AppLayout = ({
|
||||||
<div
|
<div
|
||||||
id={Ids.SubPanel}
|
id={Ids.SubPanel}
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
`texture-paper-dots z-20 overflow-y-scroll border-r border-dark/50
|
`z-20 overflow-y-scroll border-r border-dark/50 bg-light
|
||||||
bg-light transition-transform duration-300 scrollbar-none`,
|
transition-transform duration-300 scrollbar-none texture-paper-dots`,
|
||||||
cIf(
|
cIf(
|
||||||
is1ColumnLayout,
|
is1ColumnLayout,
|
||||||
"justify-self-end border-r-0 [grid-area:content]",
|
"justify-self-end border-r-0 [grid-area:content]",
|
||||||
|
@ -185,8 +185,8 @@ export const AppLayout = ({
|
||||||
{/* Main panel */}
|
{/* Main panel */}
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
`texture-paper-dots z-30 overflow-y-scroll border-r border-dark/50
|
`z-30 overflow-y-scroll border-r border-dark/50 bg-light
|
||||||
bg-light transition-transform duration-300 scrollbar-none`,
|
transition-transform duration-300 scrollbar-none texture-paper-dots`,
|
||||||
cIf(is1ColumnLayout, "justify-self-start [grid-area:content]", "[grid-area:main]"),
|
cIf(is1ColumnLayout, "justify-self-start [grid-area:content]", "[grid-area:main]"),
|
||||||
cIf(is1ColumnLayout && isScreenAtLeastXs, "w-[min(30rem,90%)]"),
|
cIf(is1ColumnLayout && isScreenAtLeastXs, "w-[min(30rem,90%)]"),
|
||||||
cIf(!mainPanelOpen && is1ColumnLayout, "-translate-x-full")
|
cIf(!mainPanelOpen && is1ColumnLayout, "-translate-x-full")
|
||||||
|
@ -197,8 +197,8 @@ export const AppLayout = ({
|
||||||
{/* Navbar */}
|
{/* Navbar */}
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
`texture-paper-dots z-10 grid grid-cols-[5rem_1fr_5rem] place-items-center
|
`z-10 grid grid-cols-[5rem_1fr_5rem] place-items-center border-t
|
||||||
border-t border-dotted border-black bg-light [grid-area:navbar]`,
|
border-dotted border-black bg-light texture-paper-dots [grid-area:navbar]`,
|
||||||
cIf(!is1ColumnLayout, "hidden")
|
cIf(!is1ColumnLayout, "hidden")
|
||||||
)}>
|
)}>
|
||||||
<Ico
|
<Ico
|
||||||
|
|
|
@ -58,7 +58,7 @@ export const OrderableList = ({ onChange, items, insertLabels }: Props): JSX.Ele
|
||||||
}}
|
}}
|
||||||
className="grid cursor-grab select-none grid-cols-[auto_1fr] place-content-center gap-2
|
className="grid cursor-grab select-none grid-cols-[auto_1fr] place-content-center gap-2
|
||||||
rounded-full border border-dark bg-light px-1 py-2 pr-4 text-dark transition-all
|
rounded-full border border-dark bg-light px-1 py-2 pr-4 text-dark transition-all
|
||||||
hover:shadow-shade hover:bg-dark hover:text-light hover:shadow-lg"
|
hover:bg-dark hover:text-light hover:shadow-lg hover:shadow-shade"
|
||||||
draggable>
|
draggable>
|
||||||
<div className="grid grid-rows-[.8em_.8em] place-items-center">
|
<div className="grid grid-rows-[.8em_.8em] place-items-center">
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const Switch = ({ value, onClick, className, disabled = false }: Props):
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
`relative grid h-6 w-12 content-center rounded-full border-mid outline
|
`relative grid h-6 w-12 content-center rounded-full border-mid outline
|
||||||
outline-1 -outline-offset-1 outline-mid transition-colors`,
|
outline-1 -outline-offset-1 outline-mid transition-colors`,
|
||||||
cIf(value, "border-none bg-mid shadow-inner-sm shadow-shade outline-transparent"),
|
cIf(value, "border-none bg-mid shadow-inner-sm outline-transparent shadow-shade"),
|
||||||
cIf(disabled, "cursor-not-allowed opacity-50 grayscale", "cursor-pointer"),
|
cIf(disabled, "cursor-not-allowed opacity-50 grayscale", "cursor-pointer"),
|
||||||
cIf(disabled, cIf(value, "bg-dark/40 outline-transparent", "outline-dark/60")),
|
cIf(disabled, cIf(value, "bg-dark/40 outline-transparent", "outline-dark/60")),
|
||||||
className
|
className
|
||||||
|
@ -36,7 +36,7 @@ export const Switch = ({ value, onClick, className, disabled = false }: Props):
|
||||||
onPointerUp={() => setIsFocused(false)}>
|
onPointerUp={() => setIsFocused(false)}>
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
"ml-1 h-4 w-4 rounded-full bg-dark transition-transform touch-none pointer-events-none",
|
"pointer-events-none ml-1 h-4 w-4 touch-none rounded-full bg-dark transition-transform",
|
||||||
cIf(value, "translate-x-6"),
|
cIf(value, "translate-x-6"),
|
||||||
cIf(isFocused, cIf(value, "translate-x-5", "translate-x-1"))
|
cIf(isFocused, cIf(value, "translate-x-5", "translate-x-1"))
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -85,8 +85,8 @@ export const LightBox = ({
|
||||||
}}>
|
}}>
|
||||||
{isDefined(src) && (
|
{isDefined(src) && (
|
||||||
<Img
|
<Img
|
||||||
className={`shadow-shade drop-shadow-2xl h-[calc(100vh-4rem)] w-full
|
className={`h-[calc(100vh-4rem)] w-full object-contain drop-shadow-2xl
|
||||||
object-contain`}
|
shadow-shade`}
|
||||||
src={src}
|
src={src}
|
||||||
quality={ImageQuality.Large}
|
quality={ImageQuality.Large}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
|
import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
import { useHotkeys } from "react-hotkeys-hook";
|
||||||
import naturalCompare from "string-natural-compare";
|
import naturalCompare from "string-natural-compare";
|
||||||
import { Chip } from "./Chip";
|
import { Chip } from "./Chip";
|
||||||
import { PageSelector } from "./Inputs/PageSelector";
|
import { PageSelector } from "./Inputs/PageSelector";
|
||||||
|
@ -9,7 +10,6 @@ import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
||||||
import { Ids } from "types/ids";
|
import { Ids } from "types/ids";
|
||||||
import { useLocalData } from "contexts/LocalDataContext";
|
import { useLocalData } from "contexts/LocalDataContext";
|
||||||
import { useContainerQueries } from "contexts/ContainerQueriesContext";
|
import { useContainerQueries } from "contexts/ContainerQueriesContext";
|
||||||
import { useHotkeys } from "react-hotkeys-hook";
|
|
||||||
|
|
||||||
interface Group<T> {
|
interface Group<T> {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -48,7 +48,7 @@ export const ThumbnailHeader = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="mb-12 grid place-items-center gap-12">
|
<div className="mb-12 grid place-items-center gap-12">
|
||||||
<div className="shadow-shade drop-shadow-lg">
|
<div className="drop-shadow-lg shadow-shade">
|
||||||
{thumbnail ? (
|
{thumbnail ? (
|
||||||
<Img
|
<Img
|
||||||
className="cursor-pointer rounded-xl"
|
className="cursor-pointer rounded-xl"
|
||||||
|
|
|
@ -177,11 +177,9 @@
|
||||||
left: -9999px;
|
left: -9999px;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
.rc-slider-tooltip * {
|
.rc-slider-tooltip * {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
.rc-slider-tooltip-hidden {
|
.rc-slider-tooltip-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
max-width: calc(100vw - 10px);
|
max-width: calc(100vw - 10px);
|
||||||
}
|
}
|
||||||
.tippy-box {
|
.tippy-box {
|
||||||
@apply relative rounded-lg bg-light transition-[transform,visibility,opacity]
|
@apply relative rounded-lg bg-light shadow-xl
|
||||||
shadow-shade shadow-xl;
|
transition-[transform,visibility,opacity] shadow-shade;
|
||||||
}
|
}
|
||||||
.tippy-box[data-placement^="top"] > .tippy-arrow {
|
.tippy-box[data-placement^="top"] > .tippy-arrow {
|
||||||
@apply bottom-0;
|
@apply bottom-0;
|
||||||
|
|
Loading…
Reference in New Issue