2024-03-19 14:49:50 -06:00

136 lines
4.3 KiB
TypeScript

import { FC, useCallback, useEffect, useState } from "react";
import { useObjectStateWrapper } from "../../hooks/useObjectState";
import { ValueField } from "./value-field";
import { HelpPopper } from "../Poppables/help";
import { Icon } from "../Icon";
import { RESERVED_FIELDS } from "../../constants/ReservedFields";
import {
fieldTypeOptions,
FieldTypes,
fieldTypesWithValues,
} from "./fieldtypes";
interface IProps {
update: (arg: FieldType) => void;
field: FieldType;
fieldName: string;
deleteField: (arg: string) => void;
}
export const FieldEditor: FC<IProps> = (
{ update, field, fieldName, deleteField },
) => {
const { bindProperty, bindPropertyCheck } = useObjectStateWrapper(
field,
(e) => update(typeof e === "function" ? e(field) : e),
);
const shouldShowValueField = useCallback(
() => fieldTypesWithValues.includes(field.type) || field.isConstant,
[field.isConstant, field.type],
);
const [reserved, setReserved] = useState<FieldType | undefined>(
RESERVED_FIELDS[fieldName],
);
useEffect(() => {
setReserved(RESERVED_FIELDS[fieldName]);
}, [fieldName]);
// useEffect(() => {
// console.log(field.value);
// }, [field])
return (
<li className="odd:bg-black/50">
<div className="flex gap-2 items-center">
<p>{fieldName}</p>
{reserved && (
<HelpPopper>
<p className="text-xs">
This is a reserved field name, these exist for internal purposes,
but are still useful when creating a type, and as such have
specific settings that you cannot override. If you need control
over the field properties, please use a different field name
</p>
</HelpPopper>
)}
</div>
{!reserved && (
<div className=" flex gap-x-4 items-center p-2 w-full">
<label className="w-min">
Field Type:&nbsp;
<select
className="capitalize"
{...bindProperty("type")}
disabled={!!reserved}
>
{fieldTypeOptions.map((o) => (
<option
key={"fieldtypes" + o}
className="capitalize"
value={FieldTypes[o]}
>
{o}
</option>
))}
</select>
</label>
{shouldShowValueField() && (
<ValueField type={field.type} bind={bindProperty("value")} />
)}
<span className="flex items-center gap-2">
<label>
<input type="checkbox" {...bindPropertyCheck("isConstant")} />
{" "}
Is constant
</label>
<HelpPopper>
<p className="text-sm">
Constant values can&apos;t be overwritten in publications. When
a dice field is set to a constant value, it instead rolls a dice
of that value whenever this field is displayed (unless
exported). This could be useful for a randomly generated
scenario or for cards being drawn as the dice value will
automatically be determined by the dice roll.
</p>
</HelpPopper>
</span>
<label className="w-min">
Minimum:
<input
className="w-12"
type="number"
{...bindProperty("minimum")}
/>
</label>
<label className="w-min">
Limit:
<input className="w-12" type="number" {...bindProperty("limit")} />
</label>
<HelpPopper>
<p className="text-sm">
Minimum and Limit apply to the number of entries allowed for this
field, not the maximum and minimum value. Set the minimum to 0 to
make a field optional. Set the limit to 0 to allow for unlimited
entries.
</p>
</HelpPopper>
<button
className="no-default self-end ml-auto"
onClick={() => deleteField(fieldName)}
>
<Icon
className="svg-red-700 hover:svg-red-500 trash-can w-6 h-6"
icon="Trash"
>
</Icon>
</button>
</div>
)}
</li>
);
};