mantine-entity
Version:
A library combining Mantine, TanStack Query, and Mantine React Table for efficient entity management
57 lines (56 loc) • 4.77 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/* eslint-disable @typescript-eslint/no-explicit-any */
import { forwardRef } from "react";
import { Table, Button, Group, ActionIcon, Stack, InputLabel, InputDescription, InputError, InputWrapper, ScrollArea, } from "@mantine/core";
import { modals } from "@mantine/modals";
import { IconEdit, IconTrash, IconPlus } from "@tabler/icons-react";
import { FormProvider, useFieldArray, useForm, } from "react-hook-form";
import { RenderElements } from "../render/render-elements";
export const TableField = forwardRef(({ field: { name, group, tableProps }, label, error, description, methods, withAsterisk, inputWrapperOrder, }, ref) => {
const { fields, append, remove, update } = useFieldArray({
control: methods.control,
name: name,
shouldUnregister: true,
});
const content = inputWrapperOrder.map((part) => {
switch (part) {
case "label":
return (_jsx(InputLabel, { required: withAsterisk, children: label }, "label"));
case "input":
return (_jsx(Table.ScrollContainer, { minWidth: 260, type: "native", className: "border rounded-md p-3 py-2 ", style: {
borderColor: error ? "var(--mantine-color-error)" : "",
}, children: _jsxs(Table, { striped: true, highlightOnHover: true, withTableBorder: true, withRowBorders: true, withColumnBorders: true, captionSide: "top", className: " rounded-md", children: [_jsx(Table.Caption, { children: _jsxs(Group, { justify: "apart", className: "w-full justify-between", children: [_jsx("span", {}), _jsx(Button, { leftSection: _jsx(IconPlus, { size: 16, stroke: 2 }), onClick: () =>
// setModal(true)
modals.open({
title: "Add Item",
id: `${name}-mod-display`,
modalId: `${name}-mod-display`,
children: (_jsx(Display, { callback: (value) => append(value), group: group, id: `${name}-mod-display`, methods: methods })),
}), size: "compact-xs", children: "Add" })] }) }), _jsx(Table.Thead, { children: _jsxs(Table.Tr, { children: [group?.map((field, i) => (_jsx(Table.Th, { fz: 12, children: field.label }, i))), _jsx(Table.Th, { fz: 12, children: "Actions" })] }) }), _jsx(Table.Tbody, { children: fields.map((value, index) => (_jsxs(Table.Tr, { children: [group?.map((field, i) => (_jsx(Table.Td, { fz: 12, children: String(value[field.name]) }, i))), _jsx(Table.Td, { children: _jsxs(Group, { gap: "xs", children: [_jsx(ActionIcon, { onClick: () => modals.open({
title: "Edit Item",
id: `${name}-mod-display-edit`,
modalId: `${name}-mod-display-edit`,
children: (_jsx(Display, { methods: methods, callback: (value) => update(index, value), value: value, group: group, id: `${name}-mod-display-edit` })),
}), variant: "outline", size: "sm", children: _jsx(IconEdit, { size: 14, stroke: 1.4 }) }), _jsx(ActionIcon, { color: "red", onClick: () => remove(index), size: "sm", variant: "outline", children: _jsx(IconTrash, { size: 14, stroke: 1.4 }) })] }) })] }, index))) })] }) }, "input"));
case "description":
return (_jsx(InputDescription, { children: description }, "description"));
case "error":
return (_jsx(InputError, { ta: "left", children: error }, "error"));
default:
return null;
}
});
return (_jsxs(InputWrapper, { ...tableProps?.wrapper, children: [_jsx("button", { ref: ref }), _jsx(ScrollArea, { ...tableProps?.root, children: content })] }));
});
TableField.displayName = "TableField";
const Display = ({ value, group, callback, id, }) => {
const methods = useForm({
defaultValues: value,
});
return (_jsx(FormProvider, { ...methods, children: _jsx("form", { id: id, onSubmit: methods.handleSubmit((value) => {
callback(value);
if (id) {
modals.close(id);
}
}), children: _jsxs(Stack, { children: [group?.map((field, i) => (_jsx(RenderElements, { element: field, methods: methods }, `${field.name}-${i}`))), _jsx(Button, { mt: "md", type: "submit", children: "save" })] }) }) }));
};