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:
2025-05-28 11:50:03 -07:00
commit 8df9031d27
3592 changed files with 319051 additions and 0 deletions
@@ -0,0 +1,55 @@
import clsx from "clsx";
import { FC, HTMLAttributes } from "react";
import { GroupedListingItem, ListingItem } from "../../types";
import { ListingGroup } from "./ListingGroup";
import { ListingItemButton } from "./ListingItemButton/ListingItemButton";
import styles from "./styles.module.css";
export interface ListingProps extends HTMLAttributes<HTMLDivElement> {
items: Array<ListingItem | GroupedListingItem>;
disabledIds?: Array<number | string>;
onQuickSelect?: (entity: ListingItem["entity"]) => void;
}
/**
* A generic listing component that displays a list of items. Items cannot be
* internal because it is used for both races/species and classes. Keeping the
* data fetch outside this component allows for more flexibility.
*/
export const Listing: FC<ListingProps> = ({
className,
items,
disabledIds,
onQuickSelect,
...props
}) => {
return (
<div className={clsx([styles.listing, className])} {...props}>
{items.length > 0 ? (
items.map((item) => {
const isDisabled = disabledIds && disabledIds.includes(item.id);
return item.type === "group" ? (
<ListingGroup
item={item as GroupedListingItem}
key={item.id + "group"}
disabledIds={disabledIds}
onQuickSelect={onQuickSelect}
/>
) : (
<ListingItemButton
item={item as ListingItem}
isDisabled={isDisabled}
key={item.id}
onQuickSelect={onQuickSelect}
/>
);
})
) : (
<p className={styles.notFound}>No Listings Found</p>
)}
</div>
);
};
@@ -0,0 +1,90 @@
import clsx from "clsx";
import { FC, HTMLAttributes, MouseEvent, useState } from "react";
import ChevronDown from "@dndbeyond/fontawesome-cache/svgs/solid/chevron-down.svg";
import { LegacyBadge } from "~/components/LegacyBadge";
import { GroupedListingItem } from "~/subApps/builder/types";
import { ListingItemButton } from "../ListingItemButton";
import styles from "./styles.module.css";
export interface ListingGroupProps extends HTMLAttributes<HTMLDetailsElement> {
item: GroupedListingItem;
disabledIds?: Array<number | string>;
onQuickSelect?: (entity: GroupedListingItem["entity"]) => void;
}
export const ListingGroup: FC<ListingGroupProps> = ({
className,
item,
disabledIds,
onQuickSelect,
...props
}) => {
const {
entityTypeId,
error,
heading,
id,
image,
isLegacy,
metaItems,
text,
type,
onClick,
...itemProps
} = item;
const [isOpen, setIsOpen] = useState<boolean>(false);
const handleToggle = (e: MouseEvent) => {
e.preventDefault();
setIsOpen(!isOpen);
};
return (
<details className={styles.details} key={id} open={isOpen} {...props}>
<summary
className={clsx([styles.summary, className])}
onClick={handleToggle}
>
{image && (
<img src={image} alt={`${heading} avatar`} className={styles.image} />
)}
<div>
<header className={styles.header}>
<h3 className={styles.heading}>
{heading}{" "}
<span
className={styles.count}
>{`(${itemProps.listItems.length})`}</span>
</h3>
{isLegacy && <LegacyBadge className={styles.tag} />}
</header>
{text && <p className={styles.text}>{text}</p>}
{metaItems && metaItems.length > 0 && (
<div className={styles.metaItems}>
{metaItems.map((metaItem, idx) => (
<span className={styles[metaItem.type]} key={idx}>
{metaItem.text}
</span>
))}
</div>
)}
</div>
<ChevronDown className={styles.icon} />
</summary>
<div className={styles.content}>
{itemProps.listItems.map((item) => (
<ListingItemButton
item={item}
isDisabled={disabledIds && disabledIds.includes(item.id)}
key={item.id}
onQuickSelect={onQuickSelect}
/>
))}
</div>
</details>
);
};
@@ -0,0 +1,78 @@
import clsx from "clsx";
import { FC, HTMLAttributes, MouseEvent } from "react";
import ChevronRight from "@dndbeyond/fontawesome-cache/svgs/solid/chevron-right.svg";
import { LegacyBadge } from "~/components/LegacyBadge";
import { ListingItem } from "~/subApps/builder/types";
import styles from "./styles.module.css";
export interface ListingItemProps extends HTMLAttributes<HTMLButtonElement> {
item: ListingItem;
isDisabled?: boolean;
onQuickSelect?: (entity: ListingItem["entity"]) => void;
}
export const ListingItemButton: FC<ListingItemProps> = ({
className,
item,
isDisabled,
onQuickSelect,
...props
}) => {
const {
entityTypeId,
error,
heading,
id,
image,
isLegacy,
metaItems,
text,
type,
onClick,
...itemProps
} = item;
const handleClick = (e: MouseEvent) => {
e.preventDefault();
//QuickSelect is from Quick and RandomBuild modes only
if (onQuickSelect && !isDisabled) {
onQuickSelect(item.entity);
} else if (onClick && !isDisabled) {
onClick(id);
}
};
return (
<button
className={clsx([styles.button, className])}
onClick={handleClick}
aria-disabled={isDisabled}
key={id}
{...props}
>
{image && (
<img src={image} alt={`${heading} avatar`} className={styles.image} />
)}
<div>
<header className={styles.header}>
<h3 className={styles.heading}>{heading}</h3>
{isLegacy && <LegacyBadge className={styles.tag} />}
</header>
{text && <p className={styles.text}>{text}</p>}
{metaItems && metaItems.length > 0 && (
<div className={styles.metaItems}>
{metaItems.map((metaItem, idx) => (
<span className={styles[metaItem.type]} key={idx}>
{metaItem.text}
</span>
))}
</div>
)}
</div>
<ChevronRight className={styles.icon} />
</button>
);
};