Grabbed dndbeyond's source code
``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import clsx from "clsx";
|
||||
import { FC, HTMLAttributes, ReactNode } from "react";
|
||||
|
||||
import { Constants } from "@dndbeyond/character-rules-engine/es";
|
||||
|
||||
import { NumberDisplayType } from "~/types";
|
||||
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
const { FEET_IN_MILES } = Constants;
|
||||
|
||||
export interface NumberDisplayProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
number: number | null;
|
||||
type: NumberDisplayType;
|
||||
isModified?: boolean;
|
||||
size?: "large";
|
||||
numberFallback?: ReactNode;
|
||||
}
|
||||
|
||||
export const NumberDisplay: FC<NumberDisplayProps> = ({
|
||||
number,
|
||||
type,
|
||||
isModified = false,
|
||||
size,
|
||||
numberFallback = "--",
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
let label = "";
|
||||
let sign = "";
|
||||
switch (type) {
|
||||
case "weightInLb":
|
||||
label = "lb.";
|
||||
number = number && Math.round((number + Number.EPSILON) * 100) / 100;
|
||||
break;
|
||||
case "distanceInFt":
|
||||
if (number && number % FEET_IN_MILES === 0) {
|
||||
number = number / FEET_IN_MILES;
|
||||
label = `mile${Math.abs(number) === 1 ? "" : "s"}`;
|
||||
} else {
|
||||
label = "ft.";
|
||||
}
|
||||
break;
|
||||
case "signed":
|
||||
if (number != null) {
|
||||
sign = number >= 0 ? "+" : "-";
|
||||
number = Math.abs(number);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className={clsx([
|
||||
styles.numberDisplay,
|
||||
type === "signed" && styles.signed,
|
||||
type === "distanceInFt" && size && styles[size + "Distance"],
|
||||
isModified && styles.modified,
|
||||
size && styles[size],
|
||||
className,
|
||||
])}
|
||||
{...props}
|
||||
>
|
||||
{type === "signed" && (
|
||||
/* NOTE: aria-label needs to go on an interactable element, not a span.
|
||||
This will need to be refactored onto the containing button.
|
||||
*/
|
||||
<span
|
||||
className={clsx([
|
||||
styles.sign,
|
||||
size && styles[size + "Sign"],
|
||||
styles.labelSignColor,
|
||||
])}
|
||||
aria-label={sign === "+" ? "plus" : "minus"}
|
||||
>
|
||||
{sign}
|
||||
</span>
|
||||
)}
|
||||
<span>{number === null ? numberFallback : number}</span>
|
||||
{type !== "signed" && (
|
||||
<span
|
||||
className={clsx([
|
||||
styles.label,
|
||||
size && styles[size + "Label"],
|
||||
styles.labelSignColor,
|
||||
])}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user