New source found from dndbeyond.com

This commit is contained in:
2026-07-08 01:00:09 -07:00
parent 9a983a6d7b
commit dcefa0d2f2
2865 changed files with 222467 additions and 49053 deletions
@@ -1,6 +1,6 @@
import React from "react";
import { MouseEvent, PureComponent, PropsWithChildren } from "react";
export interface ButtonProps {
export interface ButtonProps extends PropsWithChildren {
onClick?: ((evt: React.MouseEvent) => void) | (() => void);
clsNames?: Array<string>;
className: string;
@@ -24,7 +24,7 @@ interface ButtonState {
currentDuration: number;
confirmText: string;
}
export class Button extends React.PureComponent<ButtonProps, ButtonState> {
export class Button extends PureComponent<ButtonProps, ButtonState> {
static defaultProps = {
className: "",
styledDisabled: false,
@@ -56,7 +56,7 @@ export class Button extends React.PureComponent<ButtonProps, ButtonState> {
clearInterval(this.confirmIntervalId);
}
handleConfirmClick = (evt: React.MouseEvent<HTMLButtonElement>): void => {
handleConfirmClick = (evt: MouseEvent<HTMLButtonElement>): void => {
const { isConfirming, isConfirmed } = this.state;
const {
confirmText,
@@ -120,7 +120,7 @@ export class Button extends React.PureComponent<ButtonProps, ButtonState> {
}
};
handleClick = (evt: React.MouseEvent<HTMLButtonElement>): void => {
handleClick = (evt: MouseEvent<HTMLButtonElement>): void => {
const { onClick, stopPropagation, isInteractive } = this.props;
if (onClick && isInteractive) {
@@ -229,10 +229,10 @@ export class Button extends React.PureComponent<ButtonProps, ButtonState> {
>
<span className="ct-button__content">{children}</span>
{enableConfirm && (
<React.Fragment>
<>
<span className="ct-button__confirming">{confirmText}</span>
<span className="ct-button__confirmed" />
</React.Fragment>
</>
)}
</button>
);
@@ -1,13 +1,13 @@
import React from "react";
import { FC } from "react";
import Button, { ButtonProps } from "../Button";
//Duplicated from CharacterToolsClient
// Duplicated from CharacterToolsClient
// ToolsClient implements as a ThemeButton wrapper
// eventually RemoveButton usage should be replaced with this one with specialized style overrides
export interface RemoveButtonProps extends Partial<ButtonProps> {}
const RemoveButton: React.FunctionComponent<RemoveButtonProps> = ({
const RemoveButton: FC<RemoveButtonProps> = ({
size = "small",
style = "outline",
stopPropagation = true,
@@ -0,0 +1,6 @@
//Button and sub-buttons should be moved to common lib
import Button from "./Button";
import RemoveButton from "./RemoveButton";
export default Button;
export { Button, RemoveButton };
@@ -1,244 +0,0 @@
import React from "react";
import {
ApiAdapterPromise,
ApiAdapterUtils,
ApiResponse,
} from "@dndbeyond/character-rules-engine/es";
interface Props<T extends any = any, TData extends any = any> {
loadOptions?: () => ApiAdapterPromise<ApiResponse<Array<TData>>>;
clsNames: Array<string>;
id?: any; //TODO type?
options: Array<any>; //TODO type Options
disabled: boolean;
value: React.ReactText | null;
placeholder: string;
onChange?: (value: string) => void;
onChangePromise?: (
newValue: string,
oldValue: string,
accept: () => void,
reject: () => void
) => void;
parseLoadedOptions?: (data: Array<TData>) => Array<T>;
resetAfterChoice: boolean;
initialOptionRemoved: boolean;
preventClickPropagating: boolean;
isReadonly?: boolean;
className: string;
}
interface State {
isLazy: boolean;
lazyOptions: Array<any>;
value: React.ReactText;
resetAfterChoiceValues: Array<string>;
}
export default class Select extends React.Component<Props, State> {
static defaultProps = {
clsNames: [],
className: "",
disabled: false,
resetAfterChoice: false,
initialOptionRemoved: false,
placeholder: "-- Choose an Option --",
options: [],
preventClickPropagating: false,
};
constructor(props: Props) {
super(props);
this.state = {
isLazy: !!props.loadOptions,
lazyOptions: [],
value: props.value === null ? "" : props.value,
resetAfterChoiceValues: this.getResetAfterValueChoices(props),
};
}
componentDidUpdate(
prevProps: Readonly<Props>,
prevState: Readonly<State>,
snapshot?: any
): void {
const { value } = this.props;
if (value !== prevProps.value) {
this.setState({
value: value === null ? "" : value,
});
}
}
componentDidMount() {
const { isLazy } = this.state;
const { loadOptions, parseLoadedOptions } = this.props;
if (isLazy && loadOptions && parseLoadedOptions) {
loadOptions().then((response) => {
const data = ApiAdapterUtils.getResponseData(response);
if (data === null) {
return;
}
this.setState({
lazyOptions: parseLoadedOptions(data),
});
});
}
}
getResetAfterValueChoices = (props: Props): Array<string> => {
const { options, resetAfterChoice } = props;
if (resetAfterChoice) {
return options.reduce((acc, option) => {
if (option.options) {
acc.push(...option.options.map((opt) => "" + opt.value));
} else {
acc.push("" + option.value);
}
return acc;
}, []);
}
return options.reduce((acc, option) => {
if (option.options && option.resetAfterChoice) {
acc.push(...option.options.map((opt) => "" + opt.value));
}
return acc;
}, []);
};
handleChange = (evt: React.ChangeEvent<HTMLSelectElement>): void => {
const { value, resetAfterChoiceValues } = this.state;
const { onChangePromise, onChange, resetAfterChoice } = this.props;
const newValue: string = evt.target.value;
if (onChangePromise) {
onChangePromise(
newValue,
String(value),
() => {
this.setState({
value: newValue,
});
if (onChange) {
onChange(newValue);
}
if (resetAfterChoice) {
evt.target.selectedIndex = 0;
}
},
() => {}
);
} else {
if (resetAfterChoice || resetAfterChoiceValues.includes(newValue)) {
evt.target.selectedIndex = 0;
} else {
this.setState({
value: newValue,
});
}
if (onChange) {
onChange(newValue);
}
}
};
handleClick = (evt: React.MouseEvent): void => {
const { preventClickPropagating } = this.props;
if (preventClickPropagating) {
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
}
};
renderOption = (option: any): React.ReactNode => {
return (
<option
key={option.value}
value={String(option.value)}
disabled={option.disabled}
>
{option.label}
</option>
);
};
renderOptGroup = (
label: string,
options: Array<any>,
resetAfterChoice: boolean
) => {
if (!options.length) {
return null;
}
return (
<optgroup label={label} key={label}>
{options.map((option) => this.renderOption(option))}
</optgroup>
);
};
render() {
const { isLazy, lazyOptions, value } = this.state;
const {
options,
placeholder,
initialOptionRemoved,
id,
disabled,
clsNames,
isReadonly,
className,
} = this.props;
let displayOptions: Array<any> = options;
if (isLazy) {
displayOptions = lazyOptions;
}
const conClassNames: Array<string> = [
"ddbc-select",
...clsNames,
className,
];
return (
<select
id={id}
className={conClassNames.join(" ")}
value={value}
onChange={this.handleChange}
onClick={this.handleClick}
disabled={disabled || isReadonly}
>
<option
value=""
disabled={initialOptionRemoved}
hidden={initialOptionRemoved}
>
{placeholder}
</option>
{displayOptions.map((option) => {
if (option.options) {
return this.renderOptGroup(
option.optGroupLabel,
option.options,
option.resetAfterChoice
);
} else {
return this.renderOption(option);
}
})}
</select>
);
}
}
@@ -1,4 +0,0 @@
import Select from "./Select";
export default Select;
export { Select };