+ className="h-full overflow-scroll scroll-auto p-6 scrollbar-none">
{previousLines.map((previousLine, index) => (
{previousLine}
@@ -311,7 +310,7 @@ export const Terminal = ({
{line[carretPosition] ?? " "}
diff --git a/src/components/Panels/ContentPanel.tsx b/src/components/Containers/ContentPanel.tsx
similarity index 100%
rename from src/components/Panels/ContentPanel.tsx
rename to src/components/Containers/ContentPanel.tsx
diff --git a/src/components/Containers/DownPressable.tsx b/src/components/Containers/DownPressable.tsx
new file mode 100644
index 0000000..7852ffc
--- /dev/null
+++ b/src/components/Containers/DownPressable.tsx
@@ -0,0 +1,61 @@
+import { MouseEventHandler, useState } from "react";
+import { cJoin, cIf } from "helpers/className";
+import { Link } from "components/Inputs/Link";
+/*
+ * ╭─────────────╮
+ * ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
+ */
+
+interface Props {
+ border?: boolean;
+ active?: boolean;
+ disabled?: boolean;
+ href: string;
+ children: React.ReactNode;
+ className?: string;
+ onFocusChanged?: (isFocused: boolean) => void;
+ onClick?: MouseEventHandler;
+}
+
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
+export const DownPressable = ({
+ href,
+ border = false,
+ active = false,
+ disabled = false,
+ children,
+ className,
+ onFocusChanged,
+ onClick,
+}: Props): JSX.Element => {
+ const [isFocused, setFocused] = useState(false);
+
+ return (
+ {
+ setFocused(focus);
+ onFocusChanged?.(focus);
+ }}
+ className={cJoin(
+ `rounded-2xl p-4 transition-all`,
+ cIf(border, "outline outline-2 -outline-offset-2 outline-mid"),
+ cIf(active, "!bg-mid shadow-inner-sm outline-transparent shadow-shade"),
+ cIf(
+ disabled,
+ "cursor-not-allowed select-none opacity-50 grayscale",
+ cJoin(
+ "cursor-pointer hover:bg-mid hover:shadow-inner-sm hover:shadow-shade",
+ cIf(isFocused, "!shadow-inner !shadow-shade"),
+ cIf(border, "hover:outline-transparent")
+ )
+ ),
+ className
+ )}
+ disabled={disabled}>
+ {children}
+
+ );
+};
diff --git a/src/components/InsetBox.tsx b/src/components/Containers/InsetBox.tsx
similarity index 100%
rename from src/components/InsetBox.tsx
rename to src/components/Containers/InsetBox.tsx
diff --git a/src/components/Popup.tsx b/src/components/Containers/Popup.tsx
similarity index 100%
rename from src/components/Popup.tsx
rename to src/components/Containers/Popup.tsx
diff --git a/src/components/Panels/SubPanel.tsx b/src/components/Containers/SubPanel.tsx
similarity index 100%
rename from src/components/Panels/SubPanel.tsx
rename to src/components/Containers/SubPanel.tsx
diff --git a/src/components/Containers/UpPressable.tsx b/src/components/Containers/UpPressable.tsx
new file mode 100644
index 0000000..8c387e3
--- /dev/null
+++ b/src/components/Containers/UpPressable.tsx
@@ -0,0 +1,42 @@
+import { useState } from "react";
+import { Link } from "components/Inputs/Link";
+import { cIf, cJoin } from "helpers/className";
+
+interface Props {
+ children: React.ReactNode;
+ href: string;
+ className?: string;
+ noBackground?: boolean;
+ disabled?: boolean;
+}
+
+export const UpPressable = ({
+ children,
+ href,
+ className,
+ disabled = false,
+ noBackground = false,
+}: Props): JSX.Element => {
+ const [isFocused, setFocused] = useState(false);
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/components/Contents/PreviewFolder.tsx b/src/components/Contents/PreviewFolder.tsx
new file mode 100644
index 0000000..fe4f056
--- /dev/null
+++ b/src/components/Contents/PreviewFolder.tsx
@@ -0,0 +1,38 @@
+import { useCallback } from "react";
+import { useSmartLanguage } from "hooks/useSmartLanguage";
+import { TranslatedProps } from "types/TranslatedProps";
+import { UpPressable } from "components/Containers/UpPressable";
+import { cIf, cJoin } from "helpers/className";
+
+interface PreviewFolderProps {
+ href: string;
+ title?: string | null;
+ disabled?: boolean;
+}
+
+export const PreviewFolder = ({ href, title, disabled }: PreviewFolderProps): JSX.Element => (
+
+
+
+);
+
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
+export const TranslatedPreviewFolder = ({
+ translations,
+ fallback,
+ ...otherProps
+}: TranslatedProps): JSX.Element => {
+ const [selectedTranslation] = useSmartLanguage({
+ items: translations,
+ languageExtractor: useCallback((item: { language: string }): string => item.language, []),
+ });
+ return ;
+};
diff --git a/src/components/Inputs/Button.tsx b/src/components/Inputs/Button.tsx
index 795189a..e24569e 100644
--- a/src/components/Inputs/Button.tsx
+++ b/src/components/Inputs/Button.tsx
@@ -46,28 +46,32 @@ export const Button = ({
size = "normal",
}: Props): JSX.Element => (
!disabled && onClick?.(event)}
onMouseUp={onMouseUp}
onFocus={(event) => event.target.blur()}
className={cJoin(
`group grid cursor-pointer select-none grid-flow-col place-content-center
place-items-center gap-2 rounded-full border border-dark py-3 px-4
leading-none text-dark transition-all`,
- cIf(
- active,
- "!border-black bg-black !text-light drop-shadow-black-lg",
- `hover:bg-dark hover:text-light hover:drop-shadow-shade-lg active:hover:!border-black
- active:hover:bg-black active:hover:!text-light active:hover:drop-shadow-black-lg`
- ),
cIf(size === "small", "px-3 py-1 text-xs"),
- cIf(disabled, "cursor-not-allowed"),
+ cIf(active, "!border-black bg-black !text-light drop-shadow-lg shadow-black"),
+ cIf(
+ disabled,
+ "cursor-not-allowed opacity-50 grayscale",
+ cIf(
+ !active,
+ `shadow-shade hover:bg-dark hover:text-light hover:drop-shadow-lg
+ active:hover:!border-black active:hover:bg-black active:hover:!text-light
+ active:hover:drop-shadow-lg active:hover:shadow-black`
+ )
+ ),
className
)}>
{isDefined(badgeNumber) && (
diff --git a/src/components/Inputs/Link.tsx b/src/components/Inputs/Link.tsx
index 0df1860..8898229 100644
--- a/src/components/Inputs/Link.tsx
+++ b/src/components/Inputs/Link.tsx
@@ -1,5 +1,5 @@
import router from "next/router";
-import { MouseEventHandler, useState } from "react";
+import { PointerEventHandler, useState } from "react";
import { isDefined } from "helpers/others";
interface Props {
@@ -8,43 +8,56 @@ interface Props {
allowNewTab?: boolean;
alwaysNewTab?: boolean;
children: React.ReactNode;
- onClick?: MouseEventHandler
;
+ onClick?: PointerEventHandler;
+ onFocusChanged?: (isFocused: boolean) => void;
+ disabled?: boolean;
}
export const Link = ({
href,
allowNewTab = true,
alwaysNewTab = false,
+ disabled = false,
children,
className,
onClick,
+ onFocusChanged,
}: Props): JSX.Element => {
const [isValidClick, setIsValidClick] = useState(false);
return (
setIsValidClick(false)}
- onContextMenu={(event) => event.preventDefault()}
- onMouseDown={(event) => {
- event.preventDefault();
- setIsValidClick(true);
+ onPointerLeave={() => {
+ setIsValidClick(false);
+ onFocusChanged?.(false);
}}
- onMouseUp={(event) => {
- if (isDefined(onClick)) {
- onClick(event);
- } else if (isValidClick && href) {
- if (event.button !== MouseButton.Right) {
- if (alwaysNewTab) {
- window.open(href, "_blank", "noopener");
- } else if (event.button === MouseButton.Left) {
- if (href.startsWith("#")) {
- router.replace(href);
- } else {
- router.push(href);
+ onContextMenu={(event) => event.preventDefault()}
+ onPointerDown={(event) => {
+ if (!disabled) {
+ event.preventDefault();
+ onFocusChanged?.(true);
+ setIsValidClick(true);
+ }
+ }}
+ onPointerUp={(event) => {
+ onFocusChanged?.(false);
+ if (!disabled) {
+ if (isDefined(onClick)) {
+ onClick(event);
+ } else if (isValidClick && href) {
+ if (event.button !== MouseButton.Right) {
+ if (alwaysNewTab) {
+ window.open(href, "_blank", "noopener");
+ } else if (event.button === MouseButton.Left) {
+ if (href.startsWith("#")) {
+ router.replace(href);
+ } else {
+ router.push(href);
+ }
+ } else if (allowNewTab) {
+ window.open(href, "_blank");
}
- } else if (allowNewTab) {
- window.open(href, "_blank");
}
}
}
diff --git a/src/components/Inputs/OrderableList.tsx b/src/components/Inputs/OrderableList.tsx
index cf9c7d4..f8e7f1e 100644
--- a/src/components/Inputs/OrderableList.tsx
+++ b/src/components/Inputs/OrderableList.tsx
@@ -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
rounded-full border border-dark bg-light px-1 py-2 pr-4 text-dark transition-all
- hover:bg-dark hover:text-light hover:drop-shadow-shade-lg"
+ hover:shadow-shade hover:bg-dark hover:text-light hover:shadow-lg"
draggable>
{index > 0 && (
diff --git a/src/components/Inputs/Select.tsx b/src/components/Inputs/Select.tsx
index 60a66f1..72c1c60 100644
--- a/src/components/Inputs/Select.tsx
+++ b/src/components/Inputs/Select.tsx
@@ -15,17 +15,34 @@ interface Props {
allowEmpty?: boolean;
className?: string;
onChange: (value: number) => void;
+ disabled?: boolean;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-export const Select = ({ className, value, options, allowEmpty, onChange }: Props): JSX.Element => {
+export const Select = ({
+ className,
+ value,
+ options,
+ allowEmpty,
+ disabled = false,
+ onChange,
+}: Props): JSX.Element => {
const { value: isOpened, setFalse: setClosed, toggle: toggleOpened } = useBoolean(false);
const tryToggling = useCallback(() => {
+ if (disabled) return;
const optionCount = options.length + (value === -1 ? 1 : 0);
if (optionCount > 1) toggleOpened();
- }, [options.length, value, toggleOpened]);
+ }, [disabled, options.length, value, toggleOpened]);
+
+ const onSelectionChanged = useCallback(
+ (newIndex: number) => {
+ setClosed();
+ onChange(newIndex);
+ },
+ [onChange, setClosed]
+ );
const ref = useRef
(null);
useOnClickOutside(ref, setClosed);
@@ -35,27 +52,29 @@ export const Select = ({ className, value, options, allowEmpty, onChange }: Prop
ref={ref}
className={cJoin(
"relative text-center transition-filter",
- cIf(isOpened, "z-10 drop-shadow-shade-lg"),
+ cIf(isOpened, "z-10 drop-shadow-lg shadow-shade"),
className
)}>
-
+
{value === -1 ? "—" : options[value]}
{value >= 0 && allowEmpty && (
{
- setClosed();
- onChange(-1);
- }}
+ onClick={() => !disabled && onSelectionChanged(-1)}
/>
)}
@@ -70,10 +89,7 @@ export const Select = ({ className, value, options, allowEmpty, onChange }: Prop
cIf(isOpened, "bg-highlight", "bg-light")
)}
id={option}
- onClick={() => {
- setClosed();
- onChange(index);
- }}>
+ onClick={() => onSelectionChanged(index)}>
{option}
)}
diff --git a/src/components/Inputs/Switch.tsx b/src/components/Inputs/Switch.tsx
index c2cf389..6942767 100644
--- a/src/components/Inputs/Switch.tsx
+++ b/src/components/Inputs/Switch.tsx
@@ -22,24 +22,21 @@ export const Switch = ({ value, onClick, className, disabled = false }: Props):
className={cJoin(
`relative grid h-6 w-12 content-center rounded-full border-mid outline
outline-1 -outline-offset-1 outline-mid transition-colors`,
- cIf(disabled, "cursor-not-allowed", "cursor-pointer"),
- cIf(
- value,
- "border-none bg-mid shadow-inner-sm shadow-shade outline-transparent",
- "bg-light"
- ),
+ cIf(value, "border-none bg-mid shadow-inner-sm shadow-shade outline-transparent"),
+ cIf(disabled, "cursor-not-allowed opacity-50 grayscale", "cursor-pointer"),
+ cIf(disabled, cIf(value, "bg-dark/40 outline-transparent", "outline-dark/60")),
className
)}
onClick={() => {
if (!disabled) onClick();
}}
- onPointerDown={() => setIsFocused(true)}
+ onPointerDown={() => !disabled && setIsFocused(true)}
onPointerOut={() => setIsFocused(false)}
onPointerLeave={() => setIsFocused(false)}
onPointerUp={() => setIsFocused(false)}>
(
{
onChange(event.target.value);
@@ -38,11 +41,9 @@ export const TextInput = ({
{isDefinedAndNotEmpty(value) && (
{
- onChange("");
- }}
+ onClick={() => !disabled && onChange("")}
/>
)}
diff --git a/src/components/Inputs/WithLabel.tsx b/src/components/Inputs/WithLabel.tsx
index e2504f1..b91cb67 100644
--- a/src/components/Inputs/WithLabel.tsx
+++ b/src/components/Inputs/WithLabel.tsx
@@ -8,18 +8,13 @@ import { isDefinedAndNotEmpty } from "helpers/others";
interface Props {
label: string | null | undefined;
- disabled?: boolean;
children: React.ReactNode;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-export const WithLabel = ({ label, children, disabled }: Props): JSX.Element => (
-
+export const WithLabel = ({ label, children }: Props): JSX.Element => (
+
{isDefinedAndNotEmpty(label) && (
{label}:
)}
diff --git a/src/components/LightBox.tsx b/src/components/LightBox.tsx
index 9f8da88..eaf0bdd 100644
--- a/src/components/LightBox.tsx
+++ b/src/components/LightBox.tsx
@@ -10,15 +10,16 @@ import { Ids } from "types/ids";
import { UploadImageFragment } from "graphql/generated";
import { ImageQuality } from "helpers/img";
import { isDefined } from "helpers/others";
+import { useContainerQueries } from "contexts/ContainerQueriesContext";
interface Props {
onCloseRequest: () => void;
isVisible: boolean;
image?: UploadImageFragment | string;
- isNextImageAvailable?: boolean;
- isPreviousImageAvailable?: boolean;
- onPressNext?: () => void;
- onPressPrevious?: () => void;
+ isNextImageAvailable: boolean;
+ isPreviousImageAvailable: boolean;
+ onPressNext: () => void;
+ onPressPrevious: () => void;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
@@ -37,18 +38,15 @@ export const LightBox = ({
Ids.LightBox
);
- useHotkeys(
- "left",
- () => onPressPrevious?.(),
- { enabled: isVisible && isPreviousImageAvailable },
- [onPressPrevious]
- );
+ useHotkeys("left", () => onPressPrevious(), { enabled: isVisible && isPreviousImageAvailable }, [
+ onPressPrevious,
+ ]);
useHotkeys("f", () => requestFullscreen(), { enabled: isVisible && !isFullscreen }, [
requestFullscreen,
]);
- useHotkeys("right", () => onPressNext?.(), { enabled: isVisible && isNextImageAvailable }, [
+ useHotkeys("right", () => onPressNext(), { enabled: isVisible && isNextImageAvailable }, [
onPressNext,
]);
@@ -69,7 +67,7 @@ export const LightBox = ({
/>
{isDefined(src) && (
)}
-
- {isPreviousImageAvailable && (
-
-
-
- )}
-
- {isNextImageAvailable && (
-
- {" "}
-
- )}
-
-
- {
- resetTransform();
- exitFullscreen();
- onCloseRequest();
- }}
- icon={Icon.Close}
- />
-
-
+ {
+ resetTransform();
+ exitFullscreen();
+ onCloseRequest();
+ }}
+ onPressPrevious={() => {
+ resetTransform();
+ onPressPrevious();
+ }}
+ onPressNext={() => {
+ resetTransform();
+ onPressNext();
+ }}
+ toggleFullscreen={toggleFullscreen}
+ />
>
)}
@@ -134,3 +118,83 @@ export const LightBox = ({
);
};
+
+interface ControlButtonsProps {
+ isPreviousImageAvailable: boolean;
+ isNextImageAvailable: boolean;
+ isFullscreen: boolean;
+ onPressPrevious?: () => void;
+ onPressNext?: () => void;
+ onCloseRequest: () => void;
+ toggleFullscreen: () => void;
+}
+
+const ControlButtons = ({
+ isFullscreen,
+ isPreviousImageAvailable,
+ isNextImageAvailable,
+ onPressPrevious,
+ onPressNext,
+ onCloseRequest,
+ toggleFullscreen,
+}: ControlButtonsProps): JSX.Element => {
+ const { is1ColumnLayout } = useContainerQueries();
+
+ const PreviousButton = () => (
+
+ );
+ const NextButton = () => (
+
+ );
+
+ const FullscreenButton = () => (
+
+ );
+
+ const CloseButton = () =>
;
+
+ return is1ColumnLayout ? (
+ <>
+
+
+
+
+ >
+ ) : (
+ <>
+ {isPreviousImageAvailable && (
+
+ )}
+ {isNextImageAvailable && (
+
+
+
+ )}
+
+
+
+
+ >
+ );
+};
diff --git a/src/components/Markdown/Markdawn.tsx b/src/components/Markdown/Markdawn.tsx
index 14db799..7f00fd4 100644
--- a/src/components/Markdown/Markdawn.tsx
+++ b/src/components/Markdown/Markdawn.tsx
@@ -4,7 +4,7 @@ import React, { Fragment, useMemo } from "react";
import ReactDOMServer from "react-dom/server";
import { HorizontalLine } from "components/HorizontalLine";
import { Img } from "components/Img";
-import { InsetBox } from "components/InsetBox";
+import { InsetBox } from "components/Containers/InsetBox";
import { cIf, cJoin } from "helpers/className";
import { slugify } from "helpers/formatters";
import { getAssetURL, ImageQuality } from "helpers/img";
@@ -204,7 +204,7 @@ export const Markdawn = ({ className, text: rawText }: MarkdawnProps): JSX.Eleme
: compProps.src
}
quality={ImageQuality.Medium}
- className="drop-shadow-shade-lg"
+ className="drop-shadow-lg shadow-shade"
/>
),
diff --git a/src/components/PanelComponents/NavOption.tsx b/src/components/PanelComponents/NavOption.tsx
index 446c111..660db84 100644
--- a/src/components/PanelComponents/NavOption.tsx
+++ b/src/components/PanelComponents/NavOption.tsx
@@ -1,12 +1,12 @@
import { useRouter } from "next/router";
-import { MouseEventHandler, useCallback, useMemo } from "react";
+import { MouseEventHandler, useCallback, useMemo, useState } from "react";
import { Ico, Icon } from "components/Ico";
import { ToolTip } from "components/ToolTip";
-import { cJoin, cIf } from "helpers/className";
+import { cIf, cJoin } from "helpers/className";
import { isDefinedAndNotEmpty } from "helpers/others";
-import { Link } from "components/Inputs/Link";
import { TranslatedProps } from "types/TranslatedProps";
import { useSmartLanguage } from "hooks/useSmartLanguage";
+import { DownPressable } from "components/Containers/DownPressable";
/*
* ╭─────────────╮
@@ -21,6 +21,7 @@ interface Props {
border?: boolean;
reduced?: boolean;
active?: boolean;
+ disabled?: boolean;
onClick?: MouseEventHandler
;
}
@@ -34,6 +35,7 @@ export const NavOption = ({
border = false,
reduced = false,
active = false,
+ disabled = false,
onClick,
}: Props): JSX.Element => {
const router = useRouter();
@@ -41,6 +43,7 @@ export const NavOption = ({
() => active || router.asPath.startsWith(url),
[active, router.asPath, url]
);
+ const [isFocused, setFocused] = useState(false);
return (
-
+
- {icon && }
-
+ "grid w-full auto-cols-fr grid-flow-col grid-cols-[auto] justify-center gap-x-5",
+ cIf(icon, "text-left", "text-center")
+ )}
+ href={url}
+ border={border}
+ onClick={onClick}
+ active={isActive}
+ disabled={disabled}
+ onFocusChanged={setFocused}>
+ {icon && (
+
+ )}
{!reduced && (
{title}
{isDefinedAndNotEmpty(subtitle) &&
{subtitle}
}
)}
-
+
);
};
diff --git a/src/components/Panels/SafariPopup.tsx b/src/components/Panels/SafariPopup.tsx
index 3d83572..a208c6c 100644
--- a/src/components/Panels/SafariPopup.tsx
+++ b/src/components/Panels/SafariPopup.tsx
@@ -2,7 +2,7 @@ import { useMemo } from "react";
import UAParser from "ua-parser-js";
import { useIsClient, useSessionStorage } from "usehooks-ts";
import { Button } from "components/Inputs/Button";
-import { Popup } from "components/Popup";
+import { Popup } from "components/Containers/Popup";
import { sendAnalytics } from "helpers/analytics";
export const SafariPopup = (): JSX.Element => {
diff --git a/src/components/Panels/SettingsPopup.tsx b/src/components/Panels/SettingsPopup.tsx
index 65b6d023..609924e 100644
--- a/src/components/Panels/SettingsPopup.tsx
+++ b/src/components/Panels/SettingsPopup.tsx
@@ -6,7 +6,7 @@ import { ButtonGroup } from "components/Inputs/ButtonGroup";
import { OrderableList } from "components/Inputs/OrderableList";
import { Select } from "components/Inputs/Select";
import { TextInput } from "components/Inputs/TextInput";
-import { Popup } from "components/Popup";
+import { Popup } from "components/Containers/Popup";
import { useAppLayout } from "contexts/AppLayoutContext";
import { useLocalData } from "contexts/LocalDataContext";
import { useUserSettings } from "contexts/UserSettingsContext";
diff --git a/src/components/PostPage.tsx b/src/components/PostPage.tsx
index 05e7f45..5c13ff8 100644
--- a/src/components/PostPage.tsx
+++ b/src/components/PostPage.tsx
@@ -4,8 +4,8 @@ import { Chip } from "./Chip";
import { HorizontalLine } from "./HorizontalLine";
import { Markdawn, TableOfContents } from "./Markdown/Markdawn";
import { ReturnButton } from "./PanelComponents/ReturnButton";
-import { ContentPanel } from "./Panels/ContentPanel";
-import { SubPanel } from "./Panels/SubPanel";
+import { ContentPanel } from "./Containers/ContentPanel";
+import { SubPanel } from "./Containers/SubPanel";
import { RecorderChip } from "./RecorderChip";
import { ThumbnailHeader } from "./ThumbnailHeader";
import { ToolTip } from "./ToolTip";
diff --git a/src/components/PreviewCard.tsx b/src/components/PreviewCard.tsx
index 1bd60d1..7971dfc 100644
--- a/src/components/PreviewCard.tsx
+++ b/src/components/PreviewCard.tsx
@@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { Chip } from "./Chip";
import { Ico, Icon } from "./Ico";
import { Img } from "./Img";
-import { Link } from "./Inputs/Link";
+import { UpPressable } from "./Containers/UpPressable";
import { DatePickerFragment, PricePickerFragment, UploadImageFragment } from "graphql/generated";
import { cIf, cJoin } from "helpers/className";
import { prettyDate, prettyDuration, prettyPrice, prettyShortenNumber } from "helpers/formatters";
@@ -47,6 +47,7 @@ interface Props {
duration: number;
}
| { __typename: "anotherHoverlayName" };
+ disabled?: boolean;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
@@ -67,6 +68,7 @@ export const PreviewCard = ({
metadata,
hoverlay,
infoAppend,
+ disabled = false,
}: Props): JSX.Element => {
const { currency } = useUserSettings();
const { currencies } = useLocalData();
@@ -110,97 +112,101 @@ export const PreviewCard = ({
);
return (
-
- {thumbnail ? (
-
-
-
- {hoverlay && hoverlay.__typename === "Video" && (
- <>
-
-
-
-
- {prettyDuration(hoverlay.duration)}
-
- >
- )}
-
- ) : (
-
- )}
-
- {metadata?.position === "Top" && metadataJSX}
- {topChips && topChips.length > 0 && (
-
- {topChips.map((text, index) => (
-
- ))}
-
- )}
-
- {pre_title &&
{pre_title}
}
- {title && (
-
{title}
- )}
- {subtitle &&
{subtitle}
}
-
- {description &&
{description}
}
- {bottomChips && bottomChips.length > 0 && (
+
+
+ {thumbnail ? (
- {bottomChips.map((text, index) => (
-
- ))}
+ className="relative"
+ style={{
+ aspectRatio: thumbnailForceAspectRatio ? thumbnailAspectRatio : "unset",
+ }}>
+
+
+ {hoverlay && hoverlay.__typename === "Video" && (
+ <>
+
+
+
+
+ {prettyDuration(hoverlay.duration)}
+
+ >
+ )}
+ ) : (
+
)}
+
+ {metadata?.position === "Top" && metadataJSX}
+ {topChips && topChips.length > 0 && (
+
+ {topChips.map((text, index) => (
+
+ ))}
+
+ )}
+
+ {pre_title &&
{pre_title}
}
+ {title && (
+
{title}
+ )}
+ {subtitle &&
{subtitle}
}
+
+ {description &&
{description}
}
+ {bottomChips && bottomChips.length > 0 && (
+
+ {bottomChips.map((text, index) => (
+
+ ))}
+
+ )}
- {metadata?.position === "Bottom" && metadataJSX}
+ {metadata?.position === "Bottom" && metadataJSX}
- {infoAppend}
+ {infoAppend}
+
-
+
);
};
diff --git a/src/components/PreviewLine.tsx b/src/components/PreviewLine.tsx
index a164675..313f82e 100644
--- a/src/components/PreviewLine.tsx
+++ b/src/components/PreviewLine.tsx
@@ -1,11 +1,13 @@
import { useCallback } from "react";
import { Chip } from "./Chip";
import { Img } from "./Img";
-import { Link } from "./Inputs/Link";
+import { UpPressable } from "./Containers/UpPressable";
import { UploadImageFragment } from "graphql/generated";
import { ImageQuality } from "helpers/img";
import { TranslatedProps } from "types/TranslatedProps";
import { useSmartLanguage } from "hooks/useSmartLanguage";
+import { cIf, cJoin } from "helpers/className";
+import { isDefined } from "helpers/others";
/*
* ╭─────────────╮
@@ -14,60 +16,66 @@ import { useSmartLanguage } from "hooks/useSmartLanguage";
interface Props {
thumbnail?: UploadImageFragment | string | null | undefined;
- thumbnailAspectRatio?: string;
href: string;
pre_title?: string | null | undefined;
title: string | null | undefined;
subtitle?: string | null | undefined;
topChips?: string[];
bottomChips?: string[];
+ disabled?: boolean;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-const PreviewLine = ({
+export const PreviewLine = ({
href,
thumbnail,
pre_title,
title,
subtitle,
topChips,
+ disabled,
bottomChips,
- thumbnailAspectRatio,
}: Props): JSX.Element => (
-
- {thumbnail ? (
-
-
-
- ) : (
-
- )}
-
- {topChips && topChips.length > 0 && (
-
- {topChips.map((text, index) => (
-
- ))}
+
+
+ {thumbnail && (
+
+
)}
-
- {pre_title &&
{pre_title}
}
- {title &&
{title}
}
- {subtitle &&
{subtitle}
}
-
- {bottomChips && bottomChips.length > 0 && (
-
- {bottomChips.map((text, index) => (
-
- ))}
+
+
+ {topChips && topChips.length > 0 && (
+
+ {topChips.map((text, index) => (
+
+ ))}
+
+ )}
+
+ {pre_title &&
{pre_title}
}
+ {title &&
{title}
}
+ {subtitle &&
{subtitle}
}
- )}
+ {bottomChips && bottomChips.length > 0 && (
+
+ {bottomChips.map((text, index) => (
+
+ ))}
+
+ )}
+
-
+
);
/*
diff --git a/src/components/SmartList.tsx b/src/components/SmartList.tsx
index 3f807d1..b067acf 100644
--- a/src/components/SmartList.tsx
+++ b/src/components/SmartList.tsx
@@ -9,6 +9,7 @@ import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
import { Ids } from "types/ids";
import { useLocalData } from "contexts/LocalDataContext";
import { useContainerQueries } from "contexts/ContainerQueriesContext";
+import { useHotkeys } from "react-hotkeys-hook";
interface Group
{
name: string;
@@ -163,6 +164,11 @@ export const SmartList = ({
return memo;
}, [groups, paginationItemPerPage]);
+ useHotkeys("left", () => setPage((current) => current - 1), { enabled: page > 0 });
+ useHotkeys("right", () => setPage((current) => current + 1), {
+ enabled: page < pages.length - 1,
+ });
+
return (
<>
{pages.length > 1 && paginationSelectorTop && (
diff --git a/src/components/ThumbnailHeader.tsx b/src/components/ThumbnailHeader.tsx
index 5d22e54..1396254 100644
--- a/src/components/ThumbnailHeader.tsx
+++ b/src/components/ThumbnailHeader.tsx
@@ -1,6 +1,6 @@
import { Chip } from "components/Chip";
import { Img } from "components/Img";
-import { InsetBox } from "components/InsetBox";
+import { InsetBox } from "components/Containers/InsetBox";
import { Markdawn } from "components/Markdown/Markdawn";
import { GetContentTextQuery, UploadImageFragment } from "graphql/generated";
import { prettyInlineTitle, prettySlug, slugify } from "helpers/formatters";
@@ -48,7 +48,7 @@ export const ThumbnailHeader = ({
return (
<>
-
+
{thumbnail ? (
(condition ? ifTrueCss : ifFalseCss ?? "");
+): string => removeWhitespace(condition ? ifTrueCss : ifFalseCss ?? "");
export const cJoin = (...args: (string | undefined)[]): string =>
- args.filter((elem) => elem).join(" ");
+ removeWhitespace(args.filter((elem) => elem).join(" "));
+
+const removeWhitespace = (string: string): string => string.replaceAll(/\s+/gu, " ");
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
index a7c3d4e..496222b 100644
--- a/src/pages/404.tsx
+++ b/src/pages/404.tsx
@@ -1,7 +1,7 @@
import { GetStaticProps } from "next";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel } from "components/Panels/ContentPanel";
+import { ContentPanel } from "components/Containers/ContentPanel";
import { getOpenGraph } from "helpers/openGraph";
import { getLangui } from "graphql/fetchLocalData";
import { Img } from "components/Img";
@@ -20,7 +20,10 @@ const FourOhFour = ({ openGraph, ...otherProps }: Props): JSX.Element => {
-
+
{langui.page_not_found}
diff --git a/src/pages/500.tsx b/src/pages/500.tsx
index 260cec8..d59dc01 100644
--- a/src/pages/500.tsx
+++ b/src/pages/500.tsx
@@ -1,7 +1,7 @@
import { GetStaticProps } from "next";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel } from "components/Panels/ContentPanel";
+import { ContentPanel } from "components/Containers/ContentPanel";
import { getOpenGraph } from "helpers/openGraph";
import { getLangui } from "graphql/fetchLocalData";
import { Img } from "components/Img";
@@ -20,7 +20,10 @@ const FiveHundred = ({ openGraph, ...otherProps }: Props): JSX.Element => {
-
+
{langui.page_not_found}
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 7e2dc72..bbc6e04 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -11,8 +11,6 @@ import type { AppProps } from "next/app";
import Script from "next/script";
import { AppContextProvider } from "contexts/AppLayoutContext";
-import "styles/animations.css";
-import "styles/custom-classes.css";
import "styles/debug.css";
import "styles/formatted.css";
import "styles/others.css";
diff --git a/src/pages/about-us/contact.tsx b/src/pages/about-us/contact.tsx
index 5d9d1cd..5571c7a 100644
--- a/src/pages/about-us/contact.tsx
+++ b/src/pages/about-us/contact.tsx
@@ -1,6 +1,6 @@
import { useRouter } from "next/router";
import { useState } from "react";
-import { InsetBox } from "components/InsetBox";
+import { InsetBox } from "components/Containers/InsetBox";
import { PostPage } from "components/PostPage";
import { getPostStaticProps, PostStaticProps } from "graphql/getPostStaticProps";
import { cIf, cJoin } from "helpers/className";
diff --git a/src/pages/about-us/index.tsx b/src/pages/about-us/index.tsx
index 98fd454..a43fdd9 100644
--- a/src/pages/about-us/index.tsx
+++ b/src/pages/about-us/index.tsx
@@ -3,7 +3,7 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Icon } from "components/Ico";
import { NavOption } from "components/PanelComponents/NavOption";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { getOpenGraph } from "helpers/openGraph";
import { HorizontalLine } from "components/HorizontalLine";
import { getLangui } from "graphql/fetchLocalData";
diff --git a/src/pages/archives/index.tsx b/src/pages/archives/index.tsx
index 4d57db5..005fa18 100644
--- a/src/pages/archives/index.tsx
+++ b/src/pages/archives/index.tsx
@@ -3,7 +3,7 @@ import { useMemo } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { NavOption } from "components/PanelComponents/NavOption";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { Icon } from "components/Ico";
import { getOpenGraph } from "helpers/openGraph";
import { HorizontalLine } from "components/HorizontalLine";
diff --git a/src/pages/archives/videos/c/[uid].tsx b/src/pages/archives/videos/c/[uid].tsx
index 381d13a..8ffe8b4 100644
--- a/src/pages/archives/videos/c/[uid].tsx
+++ b/src/pages/archives/videos/c/[uid].tsx
@@ -5,8 +5,8 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Switch } from "components/Inputs/Switch";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { PreviewCard } from "components/PreviewCard";
import { GetVideoChannelQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
diff --git a/src/pages/archives/videos/index.tsx b/src/pages/archives/videos/index.tsx
index 9bb2860..936a9bf 100644
--- a/src/pages/archives/videos/index.tsx
+++ b/src/pages/archives/videos/index.tsx
@@ -9,8 +9,8 @@ import { TextInput } from "components/Inputs/TextInput";
import { WithLabel } from "components/Inputs/WithLabel";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { PreviewCard } from "components/PreviewCard";
import { GetVideosPreviewQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx
index db12a9a..095086a 100644
--- a/src/pages/archives/videos/v/[uid].tsx
+++ b/src/pages/archives/videos/v/[uid].tsx
@@ -5,11 +5,11 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { HorizontalLine } from "components/HorizontalLine";
import { Ico, Icon } from "components/Ico";
import { Button } from "components/Inputs/Button";
-import { InsetBox } from "components/InsetBox";
+import { InsetBox } from "components/Containers/InsetBox";
import { NavOption } from "components/PanelComponents/NavOption";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { useAppLayout } from "contexts/AppLayoutContext";
import { GetVideoQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
@@ -83,7 +83,7 @@ const Video = ({ video, ...otherProps }: Props): JSX.Element => {
/>
-
+
{video.gone ? (
) : (
diff --git a/src/pages/chronicles/[slug]/index.tsx b/src/pages/chronicles/[slug]/index.tsx
index b1a04be..5697a0a 100644
--- a/src/pages/chronicles/[slug]/index.tsx
+++ b/src/pages/chronicles/[slug]/index.tsx
@@ -5,9 +5,9 @@ import { isDefined, filterHasAttributes } from "helpers/others";
import { ChronicleWithTranslations } from "types/types";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { useSmartLanguage } from "hooks/useSmartLanguage";
-import { ContentPanel } from "components/Panels/ContentPanel";
+import { ContentPanel } from "components/Containers/ContentPanel";
import { Markdawn } from "components/Markdown/Markdawn";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { ThumbnailHeader } from "components/ThumbnailHeader";
import { HorizontalLine } from "components/HorizontalLine";
import { GetChroniclesChaptersQuery } from "graphql/generated";
diff --git a/src/pages/chronicles/index.tsx b/src/pages/chronicles/index.tsx
index b0a54ce..6437539 100644
--- a/src/pages/chronicles/index.tsx
+++ b/src/pages/chronicles/index.tsx
@@ -2,7 +2,7 @@ import { GetStaticProps } from "next";
import { useMemo } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { Icon } from "components/Ico";
import { getReadySdk } from "graphql/sdk";
import { GetChroniclesChaptersQuery } from "graphql/generated";
diff --git a/src/pages/contents/[slug].tsx b/src/pages/contents/[slug].tsx
index 1419d0b..d3c7050 100644
--- a/src/pages/contents/[slug].tsx
+++ b/src/pages/contents/[slug].tsx
@@ -7,8 +7,8 @@ import { HorizontalLine } from "components/HorizontalLine";
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
import { Markdawn, TableOfContents } from "components/Markdown/Markdawn";
import { TranslatedReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { PreviewCard } from "components/PreviewCard";
import { RecorderChip } from "components/RecorderChip";
import { ThumbnailHeader } from "components/ThumbnailHeader";
@@ -315,7 +315,6 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
title: prettySlug(previousContent.attributes.slug),
}}
thumbnail={previousContent.attributes.thumbnail?.data?.attributes}
- thumbnailAspectRatio="3/2"
topChips={
isContentPanelAtLeast2xl && previousContent.attributes.type?.data?.attributes
? [
@@ -359,7 +358,6 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
}))}
fallback={{ title: nextContent.attributes.slug }}
thumbnail={nextContent.attributes.thumbnail?.data?.attributes}
- thumbnailAspectRatio="3/2"
topChips={
isContentPanelAtLeast2xl && nextContent.attributes.type?.data?.attributes
? [
diff --git a/src/pages/contents/all.tsx b/src/pages/contents/all.tsx
index 186004d..cbdd32b 100644
--- a/src/pages/contents/all.tsx
+++ b/src/pages/contents/all.tsx
@@ -6,8 +6,8 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Select } from "components/Inputs/Select";
import { Switch } from "components/Inputs/Switch";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { getReadySdk } from "graphql/sdk";
import { prettyInlineTitle, prettySlug } from "helpers/formatters";
import { TextInput } from "components/Inputs/TextInput";
diff --git a/src/pages/contents/folder/[slug].tsx b/src/pages/contents/folder/[slug].tsx
index 316b3e3..f3bc266 100644
--- a/src/pages/contents/folder/[slug].tsx
+++ b/src/pages/contents/folder/[slug].tsx
@@ -1,8 +1,8 @@
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
-import { useCallback, useMemo } from "react";
+import { useMemo } from "react";
import naturalCompare from "string-natural-compare";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { getOpenGraph } from "helpers/openGraph";
import { getReadySdk } from "graphql/sdk";
import { filterHasAttributes } from "helpers/others";
@@ -12,17 +12,15 @@ import { prettySlug } from "helpers/formatters";
import { SmartList } from "components/SmartList";
import { Ico, Icon } from "components/Ico";
import { Button, TranslatedButton } from "components/Inputs/Button";
-import { Link } from "components/Inputs/Link";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { SubPanel } from "components/Panels/SubPanel";
-import { TranslatedProps } from "types/TranslatedProps";
-import { useSmartLanguage } from "hooks/useSmartLanguage";
+import { SubPanel } from "components/Containers/SubPanel";
import { TranslatedPreviewCard } from "components/PreviewCard";
import { HorizontalLine } from "components/HorizontalLine";
import { cJoin, cIf } from "helpers/className";
import { getLangui } from "graphql/fetchLocalData";
import { useLocalData } from "contexts/LocalDataContext";
import { useContainerQueries } from "contexts/ContainerQueriesContext";
+import { TranslatedPreviewFolder } from "components/Contents/PreviewFolder";
/*
* ╭────────╮
@@ -274,36 +272,6 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
* ───────────────────────────────────╯ PRIVATE COMPONENTS ╰──────────────────────────────────────
*/
-interface PreviewFolderProps {
- href: string;
- title: string | null | undefined;
-}
-
-const PreviewFolder = ({ href, title }: PreviewFolderProps): JSX.Element => (
-
- {title &&
{title}
}
-
-);
-
-// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-
-const TranslatedPreviewFolder = ({
- translations,
- fallback,
- ...otherProps
-}: TranslatedProps
): JSX.Element => {
- const [selectedTranslation] = useSmartLanguage({
- items: translations,
- languageExtractor: useCallback((item: { language: string }): string => item.language, []),
- });
- return ;
-};
-
-// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-
const NoContentNorFolderMessage = () => {
const { langui } = useLocalData();
return (
diff --git a/src/pages/dev/checkup/contents.tsx b/src/pages/dev/checkup/contents.tsx
index 0f7af7c..5758208 100644
--- a/src/pages/dev/checkup/contents.tsx
+++ b/src/pages/dev/checkup/contents.tsx
@@ -3,7 +3,7 @@ import { useMemo } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Chip } from "components/Chip";
import { Button } from "components/Inputs/Button";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { ToolTip } from "components/ToolTip";
import { DevGetContentsQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
diff --git a/src/pages/dev/checkup/libraryitems.tsx b/src/pages/dev/checkup/libraryitems.tsx
index d81e415..38ab8b1 100644
--- a/src/pages/dev/checkup/libraryitems.tsx
+++ b/src/pages/dev/checkup/libraryitems.tsx
@@ -3,7 +3,7 @@ import { useMemo } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Chip } from "components/Chip";
import { Button } from "components/Inputs/Button";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { ToolTip } from "components/ToolTip";
import {
DevGetLibraryItemsQuery,
diff --git a/src/pages/dev/editor.tsx b/src/pages/dev/editor.tsx
index f4e9e49..61f023b 100644
--- a/src/pages/dev/editor.tsx
+++ b/src/pages/dev/editor.tsx
@@ -4,8 +4,8 @@ import TurndownService from "turndown";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Button } from "components/Inputs/Button";
import { Markdawn, TableOfContents } from "components/Markdown/Markdawn";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { Popup } from "components/Popup";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { Popup } from "components/Containers/Popup";
import { ToolTip } from "components/ToolTip";
import { Icon } from "components/Ico";
import { getOpenGraph } from "helpers/openGraph";
diff --git a/src/pages/dev/showcase/design-system.tsx b/src/pages/dev/showcase/design-system.tsx
new file mode 100644
index 0000000..bdb8df7
--- /dev/null
+++ b/src/pages/dev/showcase/design-system.tsx
@@ -0,0 +1,966 @@
+/* eslint-disable id-denylist */
+import { GetStaticProps } from "next";
+import { ReactNode, useState } from "react";
+import Slider from "rc-slider";
+import { AppLayout, AppLayoutRequired } from "components/AppLayout";
+import { getLangui } from "graphql/fetchLocalData";
+import { getOpenGraph } from "helpers/openGraph";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { Button } from "components/Inputs/Button";
+import { Icon } from "components/Ico";
+import { cJoin } from "helpers/className";
+import { HorizontalLine } from "components/HorizontalLine";
+import { Switch } from "components/Inputs/Switch";
+import { TextInput } from "components/Inputs/TextInput";
+import { Select } from "components/Inputs/Select";
+import { WithLabel } from "components/Inputs/WithLabel";
+import { NavOption } from "components/PanelComponents/NavOption";
+import { ButtonGroup } from "components/Inputs/ButtonGroup";
+import { PreviewCard } from "components/PreviewCard";
+import { PreviewLine } from "components/PreviewLine";
+import { ChroniclePreview } from "components/Chronicles/ChroniclePreview";
+import { PreviewFolder } from "components/Contents/PreviewFolder";
+
+/*
+ * ╭────────╮
+ * ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
+ */
+
+interface Props extends AppLayoutRequired {}
+
+const DesignSystem = (props: Props): JSX.Element => {
+ const [switchState, setSwitchState] = useState(false);
+ const [selectState, setSelectState] = useState(0);
+ const [sliderState, setSliderState] = useState(5);
+ const [textInputState, setTextInputState] = useState("");
+ const [textAreaState, setTextAreaState] = useState("");
+ const [buttonGroupState, setButtonGroupState] = useState(0);
+
+ const contentPanel = (
+
+ Design System
+
+ Colors
+
+
+ Highlight
+ Light
+ Mid
+ Dark
+ Shade
+ Black
+
+ Light theme
+
+
+
+
+
+
+
+ Dark theme
+
+
+
+
+
+
+
+
+ Fonts
+
+
+ Vollkorn
+ Zen Maru Gothic
+ Share Tech Mono
+ Open Dyslexic
+
+ 3XL
+ Header H3XL
+
+
+ Dyslexia D3XL
+
+ 2XL
+ Header H2XL
+
+
+ Dyslexia D2XL
+
+ XL
+ Header HXL
+ Body BXL
+ Mono MXL
+ Dyslexia DXL
+
+ LG
+ Header HLG
+ Body BLG
+ Mono MLG
+ Dyslexia DLG
+
+ B
+
+ Body BB
+ Mono MB
+ Dyslexia DB
+
+ SM
+
+ Body BSM
+
+ Dyslexia DSM
+
+ XS
+
+
+
+ Dyslexia DXS
+
+
+ Elevations
+
+
+
+
+
+
+
+
+
+ Drop shadow
+
+
+
+
+
+
+
+ Black
+
+
+
+
+
+
+
+
+ Drop shadow
+
+ black
+
+
+
+
+
+
+
+
+
+ Buttons
+
+ Normal sized
+
+
+
+
Icon
+
Text
+
Icon + Text
+
+
Normal
+
+
+
+
+
Active
+
+
+
+
+
Disabled
+
+
+
+
+
Badge
+
+
+
+
+
+
+ Small sized
+
+
+
Normal
+
+
+
+
+
Active
+
+
+
+
+
Disabled
+
+
+
+
+
Badge
+
+
+
+
+
+
+ Groups
+
+
+
+
+ setButtonGroupState(0),
+ },
+ {
+ icon: Icon.AdUnits,
+ text: "Label",
+ active: buttonGroupState === 1,
+ onClick: () => setButtonGroupState(1),
+ },
+ {
+ text: "Yet another label",
+ active: buttonGroupState === 2,
+ onClick: () => setButtonGroupState(2),
+ },
+ {
+ icon: Icon.Security,
+ active: buttonGroupState === 3,
+ onClick: () => setButtonGroupState(3),
+ },
+ ]}
+ />
+
+
+
+ Inputs
+
+ Switches
+
+ null} />
+
+
+ null} />
+
+
+ null} disabled />
+
+
+ null} disabled />
+
+
+ setSwitchState((current) => !current)} />
+
+
+
+ Selects
+
+
+ null}
+ />
+
+
+
+ null}
+ />
+
+
+
+ null}
+ allowEmpty
+ />
+
+
+
+ null}
+ allowEmpty
+ disabled
+ />
+
+
+
+ setSelectState(index)}
+ allowEmpty
+ />
+
+
+
+ Text inputs
+
+
+ null} />
+
+
+
+ null} />
+
+
+
+ null} />
+
+
+
+ null} disabled />
+
+
+
+
+
+
+
+
+ Text area
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Slider
+
+
+
+
+
+
+
+
+
+ {
+ let value = 0;
+ if (Array.isArray(event)) {
+ value = event[0];
+ } else {
+ value = event;
+ }
+ setSliderState(() => value);
+ }}
+ />
+
+
+
+ Down-Pressables
+
+ Navigation Options
+
+
+
+
Title
+
+ Title
+ + Icon
+
+
+ Title
+ + Subtitle
+
+
+ Title
+ + Subtitle
+ + Icon
+
+
Reduced
+
+
Normal
+
+
+
+
+
+
+
Border
+
+
+
+
+
+
+
Active
+
+
+
+
+
+
+
+ Active
+ + Border
+
+
+
+
+
+
+
+
Disabled
+
+
+
+
+
+
+
+ Disabled
+ + Border
+
+
+
+
+
+
+
+
+ Disabled
+ + Active
+
+
+
+
+
+
+
+
+
+ Chronology Previews
+
+
+
+
Title
+
Year
+
+ Year
+ + Month
+
+
+ Year
+ + Month
+ + Day
+
+
+
Normal
+
+
+
+
+
+
Active
+
+
+
+
+
+
Disabled
+
+
+
+
+
+
+ Disabled
+
+ Active
+
+
+
+
+
+
+
+
+ Up-Pressables
+
+ Preview Cards
+
+
+
+
+
+
+
+
}
+ bottomChips={["Bottom chip 1", "Chip 2", "Chip 3", "Chip 4"]}
+ description="Eveniet occaecati qui dicta explicabo dolor.
+ Ipsum quam dolorum dolores.
+ Neque dolor nihil neque tempora.
+ Mollitia voluptates iste qui et temporibus eum omnis.
+ Itaque atque architecto maiores qui et optio."
+ hoverlay={{ __typename: "Video", duration: 465 }}
+ topChips={[
+ "Top chip 1",
+ "Chip 2",
+ "Chip 3",
+ "Chip 4",
+ "When there are too many, it overflow",
+ ]}
+ metadata={{
+ price: {
+ amount: 5.23,
+ currency: { data: { attributes: { code: "USD", rate_to_usd: 1, symbol: "$" } } },
+ },
+ releaseDate: { year: 1970, month: 1, day: 1 },
+ views: 550669,
+ position: "Bottom",
+ }}
+ />
+
+
+
}
+ bottomChips={["Bottom chip 1", "Chip 2", "Chip 3", "Chip 4"]}
+ description="Eveniet occaecati qui dicta explicabo dolor.
+ Ipsum quam dolorum dolores.
+ Neque dolor nihil neque tempora.
+ Mollitia voluptates iste qui et temporibus eum omnis.
+ Itaque atque architecto maiores qui et optio."
+ hoverlay={{ __typename: "Video", duration: 465 }}
+ topChips={[
+ "Top chip 1",
+ "Chip 2",
+ "Chip 3",
+ "Chip 4",
+ "When there are too many, it overflow",
+ ]}
+ metadata={{
+ price: {
+ amount: 5.23,
+ currency: { data: { attributes: { code: "USD", rate_to_usd: 1, symbol: "$" } } },
+ },
+ releaseDate: { year: 1970, month: 1, day: 1 },
+ views: 550669,
+ position: "Bottom",
+ }}
+ disabled
+ />
+
+
+
+ Preview Line
+
+
+
+
+ Folder Card
+
+
+
+
+ );
+ return ;
+};
+
+export default DesignSystem;
+
+/*
+ * ╭──────────────────────╮
+ * ───────────────────────────────────╯ NEXT DATA FETCHING ╰──────────────────────────────────────
+ */
+
+export const getStaticProps: GetStaticProps = (context) => {
+ const langui = getLangui(context.locale);
+ const props: Props = {
+ openGraph: getOpenGraph(langui, "Design System"),
+ };
+ return {
+ props: props,
+ };
+};
+
+/*
+ * ╭──────────────────────╮
+ * ───────────────────────────────────╯ PRIVATE COMPONENTS ╰──────────────────────────────────────
+ */
+
+interface ThemedSectionProps {
+ className?: string;
+ children?: ReactNode;
+}
+
+const TwoThemedSection = ({ children, className }: ThemedSectionProps) => (
+
+
+ {children}
+
+
+ {children}
+
+
+);
+
+const DarkThemeSection = ({ className, children }: ThemedSectionProps) => (
+ {children}
+);
+const LightThemeSection = ({ className, children }: ThemedSectionProps) => (
+ {children}
+);
+
+const WhiteSection = ({ className, children }: ThemedSectionProps) => (
+
+ {children}
+
+);
+
+interface ColorSquareProps {
+ className?: string;
+}
+
+const ColorSquare = ({ className }: ColorSquareProps) => (
+
+);
+
+interface ShadowSquareProps {
+ className?: string;
+ text: string;
+}
+
+const ShadowSquare = ({ className, text }: ShadowSquareProps) => (
+
+ {text}
+
+);
diff --git a/src/pages/dev/transcript.tsx b/src/pages/dev/transcript.tsx
index 90c11fe..e91c699 100644
--- a/src/pages/dev/transcript.tsx
+++ b/src/pages/dev/transcript.tsx
@@ -3,7 +3,7 @@ import { useCallback, useMemo, useRef, useState } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Button } from "components/Inputs/Button";
import { ButtonGroup } from "components/Inputs/ButtonGroup";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { ToolTip } from "components/ToolTip";
import { getOpenGraph } from "helpers/openGraph";
import { getLangui } from "graphql/fetchLocalData";
diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx
index eef939d..ff6eae0 100644
--- a/src/pages/library/[slug]/index.tsx
+++ b/src/pages/library/[slug]/index.tsx
@@ -7,12 +7,12 @@ import { Chip } from "components/Chip";
import { Img } from "components/Img";
import { Button } from "components/Inputs/Button";
import { Switch } from "components/Inputs/Switch";
-import { InsetBox } from "components/InsetBox";
+import { InsetBox } from "components/Containers/InsetBox";
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
import { NavOption } from "components/PanelComponents/NavOption";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { PreviewCard } from "components/PreviewCard";
import {
Enum_Componentmetadatabooks_Binding_Type,
@@ -167,7 +167,7 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
{item.thumbnail?.data?.attributes ? (
@@ -248,7 +248,7 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
{
showLightBox(
filterHasAttributes(item.gallery?.data, ["attributes"] as const).map(
@@ -258,8 +258,8 @@ const LibrarySlug = ({ item, itemId, ...otherProps }: Props): JSX.Element => {
);
}}>
diff --git a/src/pages/library/[slug]/reader.tsx b/src/pages/library/[slug]/reader.tsx
index e250665..fc4e26a 100644
--- a/src/pages/library/[slug]/reader.tsx
+++ b/src/pages/library/[slug]/reader.tsx
@@ -20,12 +20,12 @@ import {
} from "helpers/others";
import { getOpenGraph } from "helpers/openGraph";
import { getLangui } from "graphql/fetchLocalData";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { Img } from "components/Img";
import { getAssetFilename, ImageQuality } from "helpers/img";
import { cIf, cJoin } from "helpers/className";
import { clamp, isInteger } from "helpers/numbers";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { Button } from "components/Inputs/Button";
import { Icon } from "components/Ico";
import { Ids } from "types/ids";
@@ -1045,8 +1045,8 @@ const ScanSet = ({ onClickOnImage, scanSet, id, title, content }: ScanSetProps):
{pages.map((page, index) => (
{
onClickOnImage(index);
}}>
diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx
index 2a77338..5d0bfdb 100644
--- a/src/pages/library/index.tsx
+++ b/src/pages/library/index.tsx
@@ -6,8 +6,8 @@ import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Select } from "components/Inputs/Select";
import { Switch } from "components/Inputs/Switch";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { GetLibraryItemsPreviewQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
import { prettyInlineTitle, prettyItemSubType } from "helpers/formatters";
diff --git a/src/pages/merch/index.tsx b/src/pages/merch/index.tsx
index 16f3821..3edd14a 100644
--- a/src/pages/merch/index.tsx
+++ b/src/pages/merch/index.tsx
@@ -1,7 +1,7 @@
import { GetStaticProps } from "next";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { Icon } from "components/Ico";
import { getOpenGraph } from "helpers/openGraph";
import { getLangui } from "graphql/fetchLocalData";
diff --git a/src/pages/news/index.tsx b/src/pages/news/index.tsx
index 35b7b35..d8891a0 100644
--- a/src/pages/news/index.tsx
+++ b/src/pages/news/index.tsx
@@ -4,8 +4,8 @@ import { useBoolean } from "usehooks-ts";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Switch } from "components/Inputs/Switch";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { GetPostsPreviewQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
import { prettySlug } from "helpers/formatters";
diff --git a/src/pages/wiki/[slug]/index.tsx b/src/pages/wiki/[slug]/index.tsx
index cfb0966..2943da4 100644
--- a/src/pages/wiki/[slug]/index.tsx
+++ b/src/pages/wiki/[slug]/index.tsx
@@ -6,8 +6,8 @@ import { Chip } from "components/Chip";
import { HorizontalLine } from "components/HorizontalLine";
import { Img } from "components/Img";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import DefinitionCard from "components/Wiki/DefinitionCard";
import { getReadySdk } from "graphql/sdk";
import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/others";
diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx
index 6a68884..21fd03c 100644
--- a/src/pages/wiki/chronology.tsx
+++ b/src/pages/wiki/chronology.tsx
@@ -2,10 +2,10 @@ import { GetStaticProps } from "next";
import { Fragment, useCallback, useMemo } from "react";
import { useRouter } from "next/router";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
-import { InsetBox } from "components/InsetBox";
+import { InsetBox } from "components/Containers/InsetBox";
import { ReturnButton } from "components/PanelComponents/ReturnButton";
-import { ContentPanel } from "components/Panels/ContentPanel";
-import { SubPanel } from "components/Panels/SubPanel";
+import { ContentPanel } from "components/Containers/ContentPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import {
Enum_Componenttranslationschronologyitem_Status,
GetChronologyItemsQuery,
diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx
index 3ca3ea4..35c15f6 100644
--- a/src/pages/wiki/index.tsx
+++ b/src/pages/wiki/index.tsx
@@ -4,11 +4,11 @@ import { useBoolean } from "usehooks-ts";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { NavOption } from "components/PanelComponents/NavOption";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
-import { SubPanel } from "components/Panels/SubPanel";
+import { SubPanel } from "components/Containers/SubPanel";
import { Icon } from "components/Ico";
import { getReadySdk } from "graphql/sdk";
import { GetWikiPageQuery, GetWikiPagesPreviewsQuery } from "graphql/generated";
-import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel";
+import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { HorizontalLine } from "components/HorizontalLine";
import { Button } from "components/Inputs/Button";
import { Switch } from "components/Inputs/Switch";
diff --git a/src/styles/animations.css b/src/styles/animations.css
deleted file mode 100644
index f34b370..0000000
--- a/src/styles/animations.css
+++ /dev/null
@@ -1,32 +0,0 @@
-.animation-carret {
- animation-name: blink;
- animation-duration: 1s;
- animation-timing-function: step-end;
- animation-iteration-count: infinite;
-}
-
-.animate-zoom-in {
- animation-name: zoom-in;
- animation-duration: 2s;
- animation-timing-function: ease-in-out;
- animation-iteration-count: 1;
-}
-
-@keyframes zoom-in {
- 0% {
- transform: scale(0);
- }
- 100% {
- transform: scale(1);
- }
-}
-
-@keyframes blink {
- from,
- to {
- border-bottom-style: solid;
- }
- 50% {
- border-bottom-style: none;
- }
-}
diff --git a/src/styles/custom-classes.css b/src/styles/custom-classes.css
deleted file mode 100644
index e5bbe65..0000000
--- a/src/styles/custom-classes.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.texture-paper-dots {
- @apply bg-[length:10cm] bg-local [background-image:var(--theme-texture-dots)]
- [background-blend-mode:var(--theme-texture-dots-blend)];
-}
diff --git a/src/styles/others.css b/src/styles/others.css
index 5ed513c..354d548 100644
--- a/src/styles/others.css
+++ b/src/styles/others.css
@@ -7,7 +7,7 @@
}
* {
- @apply box-border scroll-m-[40vh] scroll-smooth ![-webkit-tap-highlight-color:transparent];
+ @apply box-border scroll-m-[40vh] scroll-smooth scrollbar-thin ![-webkit-tap-highlight-color:transparent];
}
h1,
@@ -32,31 +32,12 @@ mark {
@apply bg-mid px-2;
}
-/* SCROLLBARS STYLING */
-
-* {
- @apply [scrollbar-color:theme(colors.dark/1)_transparent] [scrollbar-width:thin];
-}
-
-*::-webkit-scrollbar {
- @apply w-3;
-}
-
-*::-webkit-scrollbar-track {
- @apply bg-light;
-}
-
-*::-webkit-scrollbar-thumb {
- @apply rounded-full border-2 border-solid border-light bg-dark;
-}
-
/* INPUT */
input,
textarea {
- @apply rounded-full bg-light p-2 text-center text-dark outline outline-1 -outline-offset-1
- outline-mid transition-all placeholder:text-dark placeholder:opacity-60 hover:bg-mid
- hover:outline-transparent;
+ @apply rounded-full bg-[transparent] p-2 text-center text-dark outline outline-1 -outline-offset-1
+ outline-mid transition-all placeholder:text-dark placeholder:opacity-60;
}
input::placeholder {
@@ -65,7 +46,7 @@ input::placeholder {
input:focus-visible,
textarea:focus-within {
- @apply bg-mid shadow-inner-sm shadow-shade outline-none;
+ @apply bg-mid shadow-inner-sm outline-none shadow-shade;
}
textarea {
@@ -74,7 +55,21 @@ textarea {
input[type="submit"] {
@apply grid cursor-pointer place-content-center place-items-center rounded-full border
- border-dark px-4 pt-[0.4rem] pb-[0.5rem] text-dark outline-none transition-all hover:bg-dark
- hover:text-light hover:drop-shadow-shade-lg active:border-black active:bg-black
- active:text-light active:drop-shadow-black-lg;
+ border-dark px-4 pt-[0.4rem] pb-[0.5rem] text-dark outline-none transition-all shadow-shade
+ hover:bg-dark hover:text-light hover:drop-shadow-lg active:border-black active:bg-black
+ active:text-light active:drop-shadow-lg active:shadow-black;
+}
+
+input:enabled,
+textarea:enabled {
+ @apply hover:bg-mid hover:outline-transparent;
+}
+
+input:disabled,
+textarea:disabled {
+ @apply cursor-not-allowed opacity-50 outline-dark/60 grayscale;
+}
+
+textarea {
+ @apply scrollbar-none;
}
diff --git a/src/styles/tippy.css b/src/styles/tippy.css
index 9d001b9..3022316 100644
--- a/src/styles/tippy.css
+++ b/src/styles/tippy.css
@@ -6,7 +6,7 @@
}
.tippy-box {
@apply relative rounded-lg bg-light transition-[transform,visibility,opacity]
- drop-shadow-shade-xl;
+ shadow-shade shadow-xl;
}
.tippy-box[data-placement^="top"] > .tippy-arrow {
@apply bottom-0;
diff --git a/tailwind.config.js b/tailwind.config.js
index 3f01346..9739812 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -15,6 +15,7 @@ module.exports = {
dark: "rgb(var(--theme-color-dark) /
)",
shade: "rgb(var(--theme-color-shade) / )",
black: "rgb(var(--theme-color-black) / )",
+ transparent: "transparent",
},
fontFamily: {
body: "var(--theme-font-body)",
@@ -51,22 +52,147 @@ module.exports = {
1: "0.15rem",
2: "0.17rem",
},
+ borderRadius: {
+ none: "0",
+ sm: "0.125rem",
+ DEFAULT: "0.25rem",
+ md: "0.375rem",
+ lg: "0.5rem",
+ xl: "0.75rem",
+ "2xl": "1rem",
+ "3xl": "1.25rem",
+ "4xl": "2rem",
+ full: "9999rem",
+ },
+ boxShadow: {
+ sm: "0 1px 2px 0",
+ DEFAULT: ["0 1px 3px 0", "0 1px 2px -1px"],
+ md: ["0 4px 6px -1px", "0 1px 4px -2px"],
+ lg: ["0 10px 15px -3px", "0 0 6px -4px"],
+ xl: ["0 20px 25px -5px", "0 0 10px -6px"],
+ "2xl": ["0 25px 50px -5px", "0 15px 20px -5px"],
+ inner: "inset 0 2px 4px 0",
+ "inner-sm": "inset 0 1px 4px -2px",
+ none: "0 0 #0000",
+ },
+ dropShadow: {
+ none: "0 0 var(--tw-raw-shadow-color)",
+ sm: "0 2px 1px rgb(var(--tw-raw-shadow-color) / 0.5)",
+ DEFAULT: [
+ "0 1px 2px rgb(var(--tw-raw-shadow-color) / 0.1)",
+ "0 1px 1px rgb(var(--tw-raw-shadow-color) / 0.6)",
+ ],
+ md: [
+ "0 4px 3px rgb(var(--tw-raw-shadow-color) / 0.4)",
+ "0 2px 2px rgb(var(--tw-raw-shadow-color) / 0.6)",
+ ],
+ lg: [
+ "0 10px 8px rgb(var(--tw-raw-shadow-color) / 0.5)",
+ "0 4px 4px rgb(var(--tw-raw-shadow-color) / 0.7)",
+ ],
+ xl: [
+ "0 20px 13px rgb(var(--tw-raw-shadow-color) / 0.4)",
+ "0 8px 8px rgb(var(--tw-raw-shadow-color) / 0.7)",
+ ],
+ "2xl": [
+ "0 15px 16px rgb(var(--tw-raw-shadow-color) / 0.7)",
+ "0 10px 8px rgb(var(--tw-raw-shadow-color) / 0.6)",
+ "0 0px 2px rgb(var(--tw-raw-shadow-color) / 0.2)",
+ ],
+ },
extend: {
- boxShadow: {
- "inner-sm": "inset 0 1px 4px -2px",
- },
transitionProperty: {
height: "height, max-height, min-height",
filter: "filter, backdrop-filter",
colors:
"color, background-color, border-color, text-decoration-color, fill, stroke, outline-color",
},
- outlineColor: {
- transparent: "transparent",
+ scale: {
+ 102: "1.02",
},
},
},
plugins: [
+ /* Add support for coloring drop shadows */
+ plugin(function ({ matchUtilities, theme }) {
+ matchUtilities(
+ {
+ shadow: (value) => ({
+ "--tw-raw-shadow-color": value.slice(4, value.length - 17),
+ }),
+ },
+ { values: theme("boxShadowColor") }
+ );
+ }),
+
+ /* Add support for scrollbar styling */
+ plugin(({ addUtilities, theme }) => {
+ addUtilities({
+ ".scrollbar-none": {
+ "scrollbar-width": "none",
+ "&::-webkit-scrollbar": {
+ display: "none",
+ },
+ },
+ ".scrollbar-thin": {
+ scrollbarWidth: "thin",
+ scrollbarColor: `rgb(var(--theme-color-dark)) transparent`,
+ "&::-webkit-scrollbar": {
+ width: theme("width.3"),
+ height: theme("width.3"),
+ },
+ "&::-webkit-scrollbar-track": {
+ background: "rgb(var(--theme-color-light))",
+ },
+ "&::-webkit-scrollbar-thumb": {
+ background: "rgb(var(--theme-color-dark))",
+ borderRadius: theme("borderRadius.full"),
+ borderWidth: theme("borderWidth.2"),
+ borderColor: "rgb(var(--theme-color-light))",
+ borderStyle: "solid",
+ },
+ },
+ });
+ }),
+
+ /* Add custom animations */
+ plugin(({ addComponents }) => {
+ addComponents({
+ ".animate-carret": {
+ animationName: "blink",
+ animationDuration: "1s",
+ animationTimingFunction: "step-end",
+ animationIterationCount: "infinite",
+ },
+ ".animate-zoom-in": {
+ animationName: "zoom-in",
+ animationDuration: "2s",
+ animationTimingFunction: "ease-in-out",
+ animationIterationCount: "1",
+ },
+ "@keyframes blink": {
+ from: {
+ borderBottomStyle: "solid",
+ },
+ "50%": {
+ borderBottomStyle: "none",
+ },
+ to: {
+ borderBottomStyle: "solid",
+ },
+ },
+ "@keyframes zoom-in": {
+ from: {
+ transform: "scale(0)",
+ },
+ to: {
+ transform: "scale(1)",
+ },
+ },
+ });
+ }),
+
+ /* CSS colors setters */
plugin(({ addUtilities }) => {
addUtilities({
".set-theme-light": {
@@ -92,6 +218,7 @@ module.exports = {
});
}),
+ /* CSS fonts setters */
plugin(({ addUtilities }) => {
addUtilities({
".set-theme-font-standard": {
@@ -107,75 +234,38 @@ module.exports = {
});
}),
- plugin(({ addVariant, e }) => {
- addVariant("webkit-scrollbar", ({ modifySelectors, separator }) => {
- modifySelectors(({ className }) => {
- return `.${e(`webkit-scrollbar${separator}${className}`)}::-webkit-scrollbar`;
- });
- });
- }),
-
- // Colored Dropshadow
- plugin(({ addUtilities }) => {
- addUtilities({
- ".drop-shadow-shade-md": {
- filter: `
- drop-shadow(0 4px 3px rgb(var(--theme-color-shade) / 0.15))
- drop-shadow(0 2px 2px rgb(var(--theme-color-shade) / 0.2))`,
- },
- ".drop-shadow-shade-lg": {
- filter: `
- drop-shadow(0 10px 8px rgb(var(--theme-color-shade) / 0.2))
- drop-shadow(0 4px 3px rgb(var(--theme-color-shade) / 0.4))`,
- },
- ".drop-shadow-shade-xl": {
- filter: `
- drop-shadow(0 20px 13px rgb(var(--theme-color-shade) / 0.25))
- drop-shadow(0 8px 5px rgb(var(--theme-color-shade) / 0.7))`,
- },
- ".drop-shadow-shade-2xl": {
- filter: `drop-shadow(0 25px 25px rgb(var(--theme-color-shade) / 0.8))`,
- },
-
- ".drop-shadow-black-md": {
- filter: `
- drop-shadow(0 4px 3px rgb(var(--theme-color-black) / 0.15))
- drop-shadow(0 2px 2px rgb(var(--theme-color-black) / 0.2))`,
- },
- ".drop-shadow-black-lg": {
- filter: `
- drop-shadow(0 10px 8px rgb(var(--theme-color-black) / 0.2))
- drop-shadow(0 4px 3px rgb(var(--theme-color-black) / 0.4))`,
- },
- ".drop-shadow-black-xl": {
- filter: `
- drop-shadow(0 20px 13px rgb(var(--theme-color-black) / 0.25))
- drop-shadow(0 8px 5px rgb(var(--theme-color-black) / 0.7))`,
- },
- ".drop-shadow-black-2xl": {
- filter: `drop-shadow(0 25px 25px rgb(var(--theme-color-black) / 0.8))`,
- },
- });
- }),
-
+ /* Linear background colors presets */
plugin(({ addUtilities }) => {
addUtilities({
".linearbg-obi": {
background: `linear-gradient(
to right,
rgb(var(--theme-color-mid)),
- rgb(var(--theme-color-light)) 3%,
- rgb(var(--theme-color-light)) 97%,
+ rgb(var(--theme-color-highlight)) 3%,
+ rgb(var(--theme-color-highlight)) 97%,
rgb(var(--theme-color-mid))
)`,
},
});
}),
+ /* Add support for break-wrods CSS attribute */
plugin(({ addUtilities }) => {
addUtilities({
".break-words": {
- "word-break": "break-word",
+ wordBreak: "break-word",
+ },
+ });
+ }),
+
+ /* Custom background texture */
+ plugin(({ addUtilities }) => {
+ addUtilities({
+ ".texture-paper-dots": {
+ backgroundSize: "10cm",
+ backgroundAttachment: "local",
+ backgroundImage: "var(--theme-texture-dots)",
+ backgroundBlendMode: "var(--theme-texture-dots-blend)",
},
});
}),
diff --git a/tsconfig.json b/tsconfig.json
index 875308e..5fb3c5d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "target": "ESNext",
+ "target": "ES6",
"lib": ["dom", "dom.iterable", "esnext"],
"importHelpers": true,
"allowJs": true,