New source found from dndbeyond.com
This commit is contained in:
Generated
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
arrow,
|
||||
autoPlacement,
|
||||
autoUpdate,
|
||||
FloatingArrow,
|
||||
FloatingPortal,
|
||||
offset as offsetFn,
|
||||
useFloating,
|
||||
type Placement,
|
||||
} from "@floating-ui/react";
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
cloneElement,
|
||||
useRef,
|
||||
type PropsWithChildren,
|
||||
type ReactElement,
|
||||
type Ref,
|
||||
} from "react";
|
||||
import styles from "./AnchoredPopover.module.css";
|
||||
|
||||
interface AnchoredPopoverProps<T extends HTMLElement>
|
||||
extends PropsWithChildren {
|
||||
referenceComponent: ReactElement<{ ref?: Ref<T> }>;
|
||||
allowedPlacements: Placement[];
|
||||
className?: string;
|
||||
offset?: number;
|
||||
open?: boolean;
|
||||
floatingArrow?: boolean;
|
||||
floatingArrowClassName?: string;
|
||||
}
|
||||
|
||||
export const AnchoredPopover = <T extends HTMLElement>({
|
||||
className,
|
||||
children,
|
||||
open,
|
||||
referenceComponent,
|
||||
offset,
|
||||
allowedPlacements,
|
||||
floatingArrow,
|
||||
floatingArrowClassName,
|
||||
...rest
|
||||
}: AnchoredPopoverProps<T>) => {
|
||||
const arrowRef = useRef(null);
|
||||
const { refs, floatingStyles, context, isPositioned } = useFloating({
|
||||
strategy: "fixed",
|
||||
transform: false,
|
||||
open,
|
||||
middleware: [
|
||||
offset ? offsetFn(offset) : null,
|
||||
arrow({ element: arrowRef }),
|
||||
autoPlacement({
|
||||
allowedPlacements,
|
||||
}),
|
||||
].filter(Boolean),
|
||||
whileElementsMounted: autoUpdate,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{cloneElement(referenceComponent, { ref: refs.setReference })}
|
||||
<FloatingPortal>
|
||||
<div
|
||||
ref={refs.setFloating}
|
||||
style={floatingStyles}
|
||||
className={clsx([styles.wrapper, className])}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
{floatingArrow && isPositioned && (
|
||||
<FloatingArrow
|
||||
ref={arrowRef}
|
||||
context={context}
|
||||
className={floatingArrowClassName}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</FloatingPortal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+1
-1
@@ -21,7 +21,7 @@ export interface ButtonProps
|
||||
className?: string;
|
||||
color?: "primary" | "secondary" | "success" | "info" | "warning" | "error";
|
||||
variant?: "solid" | "outline" | "text" | "tool";
|
||||
size?: "x-small" | "small" | "medium" | "large" | "x-large";
|
||||
size?: "x-small" | "smaller" | "small" | "medium" | "large" | "x-large";
|
||||
isDiv?: boolean;
|
||||
}
|
||||
|
||||
|
||||
+30
-11
@@ -40,6 +40,12 @@ export const Dialog: React.FC<DialogProps> = ({
|
||||
const handleClickBackdrop = (e?: MouseEvent) => {
|
||||
if (!e) return;
|
||||
|
||||
// Keyboard-triggered clicks (e.g. pressing Enter on a button) report
|
||||
// clientX/clientY as 0, which falls outside the dialog rect and would
|
||||
// incorrectly be treated as a backdrop click.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
|
||||
if (e.detail === 0) return;
|
||||
|
||||
const rect = dialogRef.current?.getBoundingClientRect();
|
||||
const isClickInDialog =
|
||||
rect &&
|
||||
@@ -49,17 +55,14 @@ export const Dialog: React.FC<DialogProps> = ({
|
||||
e.clientX <= rect.left + rect.width;
|
||||
|
||||
if (!isClickInDialog) {
|
||||
// Stop the click from bubbling to a parent dialog's backdrop handler,
|
||||
// so only the innermost dialog closes when its backdrop is clicked.
|
||||
e.stopPropagation();
|
||||
onBackdropClick?.();
|
||||
handleClose();
|
||||
}
|
||||
};
|
||||
|
||||
const handleEsc = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape" && open) {
|
||||
handleClose();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
// Get the element that was clicked to open the dialog
|
||||
@@ -78,11 +81,27 @@ export const Dialog: React.FC<DialogProps> = ({
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
document.addEventListener("keydown", handleEsc);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleEsc);
|
||||
};
|
||||
if (modal) {
|
||||
// The native cancel event is only fired for modal dialogs opened via
|
||||
// showModal(). The browser adds its own Escape key listener and ensures
|
||||
// the cancel event only fires on the topmost modal, so stacked dialogs
|
||||
// close one at a time.
|
||||
const dialog = dialogRef.current;
|
||||
const handleCancel = (e: Event) => {
|
||||
e.preventDefault();
|
||||
handleClose();
|
||||
};
|
||||
dialog?.addEventListener("cancel", handleCancel);
|
||||
return () => dialog?.removeEventListener("cancel", handleCancel);
|
||||
} else {
|
||||
// Non-modal dialogs don't receive the cancel event, so we fall back to
|
||||
// a document-level keydown listener.
|
||||
const handleEsc = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape" && open) handleClose();
|
||||
};
|
||||
document.addEventListener("keydown", handleEsc);
|
||||
return () => document.removeEventListener("keydown", handleEsc);
|
||||
}
|
||||
},
|
||||
//eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[modal, open],
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import clsx from "clsx";
|
||||
import type { FC } from "react";
|
||||
import { Button, type ButtonProps } from "../Button";
|
||||
import styles from "./FancyButton.module.css";
|
||||
|
||||
interface FancyButtonProps extends Omit<ButtonProps, "color"> {
|
||||
color: "light" | "red" | "dark";
|
||||
}
|
||||
|
||||
export const FancyButton: FC<FancyButtonProps> = ({
|
||||
className,
|
||||
color = "light",
|
||||
children,
|
||||
...props
|
||||
}) => (
|
||||
<Button
|
||||
className={clsx([styles.button, styles[`${color}Button`], className])}
|
||||
{...props}
|
||||
>
|
||||
<img
|
||||
className={styles.image}
|
||||
src={
|
||||
color === "red"
|
||||
? "https://media.dndbeyond.com/images/campaigns/redButtonBorder.png"
|
||||
: "https://media.dndbeyond.com/images/campaigns/goldButtonBorder.png"
|
||||
}
|
||||
alt=""
|
||||
/>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
+696
File diff suppressed because one or more lines are too long
-49
@@ -1,49 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import type { FC, HTMLAttributes } from "react";
|
||||
import styles from "./InfoItem.module.css";
|
||||
|
||||
interface InfoItemProps extends HTMLAttributes<HTMLDivElement> {
|
||||
center?: boolean;
|
||||
color?: "primary" | "secondary" | "success" | "info" | "warning" | "error";
|
||||
label: string;
|
||||
inline?: boolean;
|
||||
italic?: boolean;
|
||||
}
|
||||
|
||||
export const InfoItem: FC<InfoItemProps> = ({
|
||||
center,
|
||||
color,
|
||||
className,
|
||||
inline,
|
||||
italic,
|
||||
label,
|
||||
children,
|
||||
...props
|
||||
}) => (
|
||||
<div
|
||||
className={clsx([
|
||||
center && styles.center,
|
||||
inline && styles.inline,
|
||||
className,
|
||||
])}
|
||||
{...props}
|
||||
>
|
||||
<p
|
||||
className={clsx([
|
||||
styles.label,
|
||||
color && styles[color],
|
||||
italic && styles.italic,
|
||||
])}
|
||||
>
|
||||
{label}
|
||||
</p>
|
||||
{typeof children === "string" ? (
|
||||
<p
|
||||
className={clsx([styles.value, color && styles[color]])}
|
||||
dangerouslySetInnerHTML={{ __html: children }}
|
||||
/>
|
||||
) : (
|
||||
<p className={clsx([styles.value, color && styles[color]])}>{children}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
Generated
Vendored
-45
@@ -1,45 +0,0 @@
|
||||
const ddbImageBase = "https://media.dndbeyond.com/mega-menu";
|
||||
|
||||
export const cardList = [
|
||||
{
|
||||
label: "Classes",
|
||||
imageUrl: `${ddbImageBase}/aef3e4b2ac24457aa251c761d41ff07b.jpg`,
|
||||
link: "https://www.dndbeyond.com/classes",
|
||||
},
|
||||
{
|
||||
label: "Backgrounds",
|
||||
imageUrl: `${ddbImageBase}/6e31ff6ea1f04ca2af9896f3f6d1b383.jpg`,
|
||||
link: "https://www.dndbeyond.com/backgrounds",
|
||||
},
|
||||
{
|
||||
label: "Species",
|
||||
imageUrl: `${ddbImageBase}/8b551f9a1c2c4db09d65cdd7c139f9d5.jpg`,
|
||||
link: `https://www.dndbeyond.com/species`,
|
||||
},
|
||||
{
|
||||
label: "Feats",
|
||||
imageUrl: `${ddbImageBase}/a69ab5bf67b03308893b582dbef700e9.jpg`,
|
||||
link: "https://www.dndbeyond.com/feats",
|
||||
},
|
||||
{
|
||||
label: "Spells",
|
||||
imageUrl: `${ddbImageBase}/a9eac9081b6240ca8d6325ca4766345e.png`,
|
||||
link: "https://www.dndbeyond.com/spells",
|
||||
},
|
||||
{
|
||||
label: "Equipment",
|
||||
imageUrl: `${ddbImageBase}/b778ff3ca3f18e5f75ad4b348615cab5.jpg`,
|
||||
link: "https://www.dndbeyond.com/equipment",
|
||||
},
|
||||
{
|
||||
label: "Magic Items",
|
||||
imageUrl: `${ddbImageBase}/c06b79eae8ee234d1cea4688e117152b.jpg`,
|
||||
link: "https://www.dndbeyond.com/magic-items",
|
||||
},
|
||||
{
|
||||
label: "Monsters",
|
||||
imageUrl: `${ddbImageBase}/36ee49066331fc36e3b37147d123463a.jpg`,
|
||||
imagePosition: "center 11%",
|
||||
link: "https://www.dndbeyond.com/monsters",
|
||||
},
|
||||
];
|
||||
Generated
Vendored
-26
@@ -1,26 +0,0 @@
|
||||
import { twitchUrl, youtubeUrl } from "../../../shared/constants";
|
||||
|
||||
const ddbImageBase = "https://media.dndbeyond.com/mega-menu";
|
||||
|
||||
export const primaryItems = [
|
||||
{
|
||||
label: "Community Update",
|
||||
imageUrl: `${ddbImageBase}/c2979f81837d8ee7c113a874da2909db.png`,
|
||||
link: "https://www.dndbeyond.com/community-update",
|
||||
},
|
||||
{
|
||||
label: "Twitch",
|
||||
imageUrl: `${ddbImageBase}/443085c3173d345e90d29881d8442a59.png`,
|
||||
link: twitchUrl,
|
||||
},
|
||||
{
|
||||
label: "Youtube",
|
||||
imageUrl: `${ddbImageBase}/d5e1b6d07482834ebfcbc1f04bd6476d.png`,
|
||||
link: youtubeUrl,
|
||||
},
|
||||
{
|
||||
label: "Changelog",
|
||||
imageUrl: `${ddbImageBase}/4af3d4c196428ab0809cf71d332d540d.png`,
|
||||
link: "https://www.dndbeyond.com/changelog",
|
||||
},
|
||||
];
|
||||
Generated
Vendored
-45
@@ -1,45 +0,0 @@
|
||||
import type { MegaMenuCardProps } from "../MegaMenuCard";
|
||||
|
||||
const ddbImageBase = "https://media.dndbeyond.com/mega-menu";
|
||||
|
||||
export const groupOne: MegaMenuCardProps[] = [
|
||||
{
|
||||
label: "Character Builder",
|
||||
imageUrl: `${ddbImageBase}/character_builder.png`,
|
||||
link: "https://www.dndbeyond.com/characters/builder",
|
||||
},
|
||||
{
|
||||
label: "Sigil 3D VTT",
|
||||
imageUrl: `${ddbImageBase}/playtest_sigil.png`,
|
||||
link: "https://www.dndbeyond.com/project-sigil",
|
||||
flags: [{ label: "New", variant: "success" }],
|
||||
},
|
||||
];
|
||||
|
||||
export const groupTwo: MegaMenuCardProps[] = [
|
||||
{
|
||||
label: "Maps VTT",
|
||||
imageUrl: `${ddbImageBase}/049ddb9085342521d25c5230451cfd45.jpg`,
|
||||
link: "https://www.dndbeyond.com/games",
|
||||
flags: [{ label: "Beta", variant: "info" }],
|
||||
},
|
||||
{
|
||||
label: "Encounters",
|
||||
imageUrl: `${ddbImageBase}/e434a8385f9619f0d52480c3c3987059.jpg`,
|
||||
link: "https://www.dndbeyond.com/encounter-builder",
|
||||
flags: [{ label: "Beta", variant: "info" }],
|
||||
},
|
||||
];
|
||||
|
||||
export const groupThree: MegaMenuCardProps[] = [
|
||||
{
|
||||
label: "Mobile App",
|
||||
imageUrl: `${ddbImageBase}/3aa58aac2d02bb52d62204e158b48ce6.jpg`,
|
||||
link: "https://www.dndbeyond.com/player-app",
|
||||
},
|
||||
{
|
||||
label: "Avrae Discord Bot",
|
||||
imageUrl: `${ddbImageBase}/28d923cd45ad209411ef1ff07993721b.jpg`,
|
||||
link: "https://avrae.io/",
|
||||
},
|
||||
];
|
||||
Generated
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
"use client";
|
||||
|
||||
import type { FC, HTMLAttributes } from "react";
|
||||
import { FancyButton } from "../FancyButton";
|
||||
import { SpinnerIcon } from "../Icons";
|
||||
import styles from "./PremadeCharacterCard.module.css";
|
||||
|
||||
interface PremadeCharacterCardProps extends HTMLAttributes<HTMLDivElement> {
|
||||
characterLevel: number;
|
||||
characterName: string;
|
||||
characterId?: number;
|
||||
primaryClassName: string;
|
||||
speciesName: string;
|
||||
longDescription: string;
|
||||
imageUrl: string;
|
||||
imageAlt: string;
|
||||
createButtonText?: string;
|
||||
showProgress: boolean;
|
||||
previewLink: string;
|
||||
onClaim: () => void;
|
||||
disableClaim?: boolean;
|
||||
}
|
||||
|
||||
export const PremadeCharacterCard: FC<PremadeCharacterCardProps> = ({
|
||||
characterLevel,
|
||||
characterName,
|
||||
characterId,
|
||||
primaryClassName,
|
||||
speciesName,
|
||||
longDescription,
|
||||
imageUrl,
|
||||
imageAlt,
|
||||
createButtonText = "Create",
|
||||
showProgress,
|
||||
previewLink,
|
||||
onClaim,
|
||||
disableClaim = false,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<div className={styles.container} {...props}>
|
||||
<img className={styles.image} src={imageUrl} alt={imageAlt} />
|
||||
<h2 className={styles.title} id={characterId?.toString()}>
|
||||
{characterName}
|
||||
</h2>
|
||||
<h3 className={styles.subTitle}>
|
||||
Level {characterLevel}: {speciesName}{" "}
|
||||
<strong>{primaryClassName}</strong>
|
||||
</h3>
|
||||
|
||||
<p className={styles.description}>{longDescription}</p>
|
||||
<FancyButton
|
||||
className={styles.button}
|
||||
color="light"
|
||||
href={previewLink}
|
||||
aria-label={`Preview ${speciesName} ${primaryClassName}`}
|
||||
>
|
||||
Preview
|
||||
</FancyButton>
|
||||
<FancyButton
|
||||
className={styles.fancyButton}
|
||||
onClick={disableClaim ? undefined : onClaim}
|
||||
color={"dark"}
|
||||
disabled={disableClaim}
|
||||
aria-label={
|
||||
showProgress
|
||||
? `Loading ${speciesName} ${primaryClassName}...`
|
||||
: `${createButtonText} ${speciesName} ${primaryClassName}`
|
||||
}
|
||||
>
|
||||
{showProgress ? <SpinnerIcon /> : createButtonText}
|
||||
</FancyButton>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
+5
-2
@@ -64,7 +64,7 @@ export const Select: FC<SelectProps> = ({
|
||||
}
|
||||
// If value is string, show string
|
||||
else if (!multiple && value) {
|
||||
return value;
|
||||
return options.find((option) => option.value === value)?.label || value;
|
||||
}
|
||||
// If there is no value, show the placeholder
|
||||
else {
|
||||
@@ -114,7 +114,10 @@ export const Select: FC<SelectProps> = ({
|
||||
type="radio"
|
||||
name={name}
|
||||
value={option.value}
|
||||
onChange={(e) => onChange?.(e)}
|
||||
onChange={(e) => {
|
||||
onChange?.(e);
|
||||
setIsVisible(false);
|
||||
}}
|
||||
checked={value === option.value}
|
||||
/>
|
||||
{option.label}
|
||||
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
import { ThemeOptions } from "@mui/material";
|
||||
|
||||
export const components: ThemeOptions["components"] = {
|
||||
MuiButtonBase: {
|
||||
defaultProps: {
|
||||
disableRipple: true,
|
||||
},
|
||||
},
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: ({ theme }) => ({
|
||||
minWidth: 320,
|
||||
"&.MuiPaper-rounded": {
|
||||
borderRadius: "8px",
|
||||
},
|
||||
"&.MuiPaper-outlined": {
|
||||
borderColor: theme.palette.primary.main,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
MuiGrid: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
/**
|
||||
* n.b. this is a workaround for bad types on the DialogTitle component,
|
||||
* what I really want there is a Grid, but I don't want to enforce these
|
||||
* styles on any other Grid components that might be passed in, so I add
|
||||
* the className "DdbDialogTitle-root" to target this specific component
|
||||
*/
|
||||
"&.DdbDialogTitle-root": {
|
||||
padding: "16px 20px 8px",
|
||||
"& .MuiIconButton-root": {
|
||||
padding: "4px",
|
||||
marginRight: "-8px",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiIconButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
transition: "none",
|
||||
"&:hover": {
|
||||
transition: "none",
|
||||
borderRadius: "3px",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialogContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: "16px 20px 0",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialogContentText: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
color: theme.palette.text.primary,
|
||||
letterSpacing: "0.15px",
|
||||
marginBottom: "12px",
|
||||
}),
|
||||
},
|
||||
},
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontSize: "15px",
|
||||
lineHeight: 26 / 15,
|
||||
letterSpacing: "0.45px",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
import { ThemeOptions } from "@mui/material";
|
||||
|
||||
export const palette: ThemeOptions["palette"] = {
|
||||
mode: "dark",
|
||||
text: {
|
||||
primary: "#ecedeeff",
|
||||
secondary: "#ecedeea3",
|
||||
disabled: "#ecedee5c",
|
||||
},
|
||||
primary: {
|
||||
main: "#dcdfe1ff",
|
||||
dark: "#75838bff",
|
||||
light: "#f9fafaff",
|
||||
contrastText: "#000000ff",
|
||||
},
|
||||
secondary: {
|
||||
main: "#00daa6ff",
|
||||
dark: "#00b674ff",
|
||||
light: "#b3efd9ff",
|
||||
contrastText: "#000000ff",
|
||||
},
|
||||
action: {
|
||||
active: "#dcdfe1a3",
|
||||
hover: "#dcdfe11f",
|
||||
selected: "#dcdfe12e",
|
||||
disabled: "#dcdfe166",
|
||||
disabledBackground: "#dcdfe133",
|
||||
focus: "#dcdfe133",
|
||||
},
|
||||
error: {
|
||||
main: "#ed6c02ff",
|
||||
dark: "#c77700ff",
|
||||
light: "#ffb547ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
warning: {
|
||||
main: "#ed6c02ff",
|
||||
dark: "#c77700ff",
|
||||
light: "#ffb547ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
info: {
|
||||
main: "#2196f3ff",
|
||||
dark: "#0b79d0ff",
|
||||
light: "#64b6f7ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
success: {
|
||||
main: "#4caf50ff",
|
||||
dark: "#3b873eff",
|
||||
light: "#7bc67eff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
background: {
|
||||
paper: "#12181cff",
|
||||
default: "#232b2fff",
|
||||
pane: "#12181cdb",
|
||||
},
|
||||
common: { white: "#ffffffff", black: "#000000ff" },
|
||||
grey: {
|
||||
"50": "#f4f5f5ff",
|
||||
"100": "#ecedeeff",
|
||||
"200": "#dcdfe1ff",
|
||||
"300": "#c4cbceff",
|
||||
"400": "#a2acb2ff",
|
||||
"500": "#75838bff",
|
||||
"600": "#525c63ff",
|
||||
"700": "#374045ff",
|
||||
"800": "#232b2fff",
|
||||
"900": "#12181cff",
|
||||
},
|
||||
rarity: {
|
||||
uncommon: "#7ebe15ff",
|
||||
rare: "#41a9f2ff",
|
||||
veryRare: "#c364e7ff",
|
||||
legendary: "#ffb62aff",
|
||||
artifact: "#f77558ff",
|
||||
contrastText: "#000000ff",
|
||||
},
|
||||
reference: {
|
||||
magicItem: "#41a9f2ff",
|
||||
monster: "#f77558ff",
|
||||
skill: "#7ebe15ff",
|
||||
spell: "#c364e7ff",
|
||||
contrastText: "#000000ff",
|
||||
},
|
||||
message: {
|
||||
check: "#c364e7ff",
|
||||
custom: "#ecedeea3",
|
||||
damage: "#f77558ff",
|
||||
healSave: "#7ebe15ff",
|
||||
initiative: "#ffb62aff",
|
||||
toHit: "#41a9f2ff",
|
||||
},
|
||||
};
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
import { ThemeOptions } from "@mui/material";
|
||||
|
||||
export const palette: ThemeOptions["palette"] = {
|
||||
mode: "light",
|
||||
text: {
|
||||
primary: "#12181cff",
|
||||
secondary: "#12181ca3",
|
||||
disabled: "#12181c5c",
|
||||
},
|
||||
primary: {
|
||||
main: "#374045ff",
|
||||
dark: "#12181cff",
|
||||
light: "#75838bff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
secondary: {
|
||||
main: "#e40712ff",
|
||||
dark: "#9f271dff",
|
||||
light: "#f77558ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
action: {
|
||||
active: "#12181ca3",
|
||||
hover: "#12181c14",
|
||||
selected: "#12181c1f",
|
||||
disabled: "#12181c5c",
|
||||
disabledBackground: "#12181c29",
|
||||
focus: "#12181c29",
|
||||
},
|
||||
error: {
|
||||
main: "#ed6c02ff",
|
||||
dark: "#c77700ff",
|
||||
light: "#ffb547ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
warning: {
|
||||
main: "#ed6c02ff",
|
||||
dark: "#c77700ff",
|
||||
light: "#ffb547ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
info: {
|
||||
main: "#2196f3ff",
|
||||
dark: "#0b79d0ff",
|
||||
light: "#64b6f7ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
success: {
|
||||
main: "#4caf50ff",
|
||||
dark: "#3b873eff",
|
||||
light: "#7bc67eff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
background: {
|
||||
paper: "#ffffffff",
|
||||
default: "#f4f5f5ff",
|
||||
parchment: "#f9f6efff",
|
||||
scroll: "#eee8dbff",
|
||||
},
|
||||
common: { white: "#ffffffff", black: "#000000ff" },
|
||||
grey: {
|
||||
"50": "#f4f5f5ff",
|
||||
"100": "#ecedeeff",
|
||||
"200": "#dcdfe1ff",
|
||||
"300": "#c4cbceff",
|
||||
"400": "#a2acb2ff",
|
||||
"500": "#75838bff",
|
||||
"600": "#525c63ff",
|
||||
"700": "#374045ff",
|
||||
"800": "#232b2fff",
|
||||
"900": "#12181cff",
|
||||
},
|
||||
rarity: {
|
||||
uncommon: "#009158ff",
|
||||
rare: "#077bd0ff",
|
||||
veryRare: "#9605d4ff",
|
||||
legendary: "#ae5e21ff",
|
||||
artifact: "#c81e18ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
reference: {
|
||||
character: "#ee8600ff",
|
||||
magicItem: "#077bd0ff",
|
||||
monster: "#c60000ff",
|
||||
skill: "#009158ff",
|
||||
spell: "#9605d4ff",
|
||||
contrastText: "#ffffffff",
|
||||
},
|
||||
};
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
import { ThemeOptions } from "@mui/material";
|
||||
|
||||
export const typography: ThemeOptions["typography"] = {
|
||||
h1: {
|
||||
fontSize: "64px",
|
||||
fontFamily: "Tiamat Condensed SC",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 1,
|
||||
lineHeight: "64px",
|
||||
},
|
||||
h2: {
|
||||
fontSize: "48px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: "normal",
|
||||
lineHeight: "52.8px",
|
||||
},
|
||||
h3: {
|
||||
fontSize: "36px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: "normal",
|
||||
lineHeight: "43.2px",
|
||||
},
|
||||
h4: {
|
||||
fontSize: "26px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: "normal",
|
||||
lineHeight: "32.5px",
|
||||
},
|
||||
h5: {
|
||||
fontSize: "20px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: "normal",
|
||||
lineHeight: "25px",
|
||||
},
|
||||
h6: {
|
||||
fontSize: "16px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: "normal",
|
||||
lineHeight: "22.4px",
|
||||
},
|
||||
body1: {
|
||||
fontSize: "16px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 0.15,
|
||||
lineHeight: "24px",
|
||||
},
|
||||
body2: {
|
||||
fontSize: "14px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 0.15,
|
||||
lineHeight: "20.02px",
|
||||
},
|
||||
subtitle1: {
|
||||
fontSize: "16px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 0.15,
|
||||
lineHeight: "28px",
|
||||
},
|
||||
subtitle2: {
|
||||
fontSize: "14px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 500,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 0.1,
|
||||
lineHeight: "21.98px",
|
||||
},
|
||||
overline: {
|
||||
fontSize: "12px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 1,
|
||||
lineHeight: "31.92px",
|
||||
textTransform: "uppercase",
|
||||
},
|
||||
caption: {
|
||||
fontSize: "12px",
|
||||
fontFamily: "Roboto",
|
||||
fontWeight: 400,
|
||||
fontStyle: "normal",
|
||||
fontStretch: "normal",
|
||||
letterSpacing: 0.4,
|
||||
lineHeight: "19.92px",
|
||||
},
|
||||
};
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
import { createTheme, ThemeOptions } from "@mui/material";
|
||||
import { deepmerge } from "@mui/utils";
|
||||
import { components } from "./config/components";
|
||||
import { palette as darkThemePalette } from "./config/palette-dark";
|
||||
import { palette as lightThemePalette } from "./config/palette-light";
|
||||
import { typography } from "./config/typography";
|
||||
|
||||
export const createLightTheme = (options: ThemeOptions = {}) =>
|
||||
createTheme(
|
||||
deepmerge(
|
||||
{
|
||||
components,
|
||||
palette: lightThemePalette,
|
||||
typography,
|
||||
},
|
||||
options,
|
||||
),
|
||||
);
|
||||
|
||||
export const createDarkTheme = (options: ThemeOptions = {}) =>
|
||||
createTheme(
|
||||
deepmerge(
|
||||
{
|
||||
components,
|
||||
palette: darkThemePalette,
|
||||
typography,
|
||||
},
|
||||
options,
|
||||
),
|
||||
);
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
export const signInLabel = "Sign In";
|
||||
export const signUpLabel = "Sign Up";
|
||||
export const signOutLabel = "Sign Out";
|
||||
|
||||
// Social Media Links
|
||||
export const discordUrl = "https://www.dndbeyond.com/discord";
|
||||
export const facebookUrl = "https://www.facebook.com/dndbeyond";
|
||||
export const instagramUrl = "https://www.instagram.com/dndbeyond";
|
||||
export const tiktokUrl = "https://www.tiktok.com/@dnd_beyond";
|
||||
export const twitchUrl = "https://www.twitch.tv/dndbeyond";
|
||||
export const twitterUrl = "https://twitter.com/dndbeyond";
|
||||
export const youtubeUrl =
|
||||
"https://www.youtube.com/channel/UCPy-338BEVgDkQade0qJmkw";
|
||||
export const googleStoreUrl =
|
||||
"https://play.google.com/store/apps/details?id=com.fandom.playercompanion";
|
||||
export const appleStoreUrl =
|
||||
"https://apps.apple.com/us/app/d-d-beyond/id1501810129";
|
||||
Reference in New Issue
Block a user