strapi-plugin-generic-custom-fields
Version:
This plugin allows you to easily add custom fields to Strapi.
146 lines (145 loc) • 5.23 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useFetchClient, useField } from "@strapi/strapi/admin";
import { useState, useCallback, useEffect } from "react";
import { DesignSystemProvider, Field, Combobox, ComboboxOption } from "@strapi/design-system";
import { useDebounce } from "@uidotdev/usehooks";
import { useTheme, styled } from "styled-components";
import { P as PLUGIN_ID } from "./index-nFd0afWV.mjs";
const IconStyled = styled.div`
width: 2em;
height: 2em;
display: inline-block;
margin-right: 0.75em;
vertical-align: middle;
background-color: currentColor;
${({ src, colorMask }) => colorMask ? `
mask-image: url(${src});
mask-repeat: no-repeat;
mask-size: 100% 100%;
-webkit-mask-image: url(${src});
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100% 100%;
` : `
background-image: url(${src});
background-repeat: no-repeat;
background-size: contain;
background-position: center;
`}
`;
const Icon = ({ src, alt, colorMask }) => {
return /* @__PURE__ */ jsx(IconStyled, { src, "aria-label": alt, colorMask });
};
const Input = (props) => {
const theme = useTheme();
const { get } = useFetchClient();
const customFieldUID = props.attribute.customField;
const field = useField(props.name);
const [loading, setLoading] = useState(true);
const [items, setItems] = useState(void 0);
const [filter, setFilter] = useState("");
const debouncedFilter = useDebounce(filter, 600);
const [customFieldConfig, setCustomFieldConfig] = useState(void 0);
const [selectedItem, setSelectedItem] = useState(void 0);
const loadFieldConfig = useCallback(async (localCustomFieldUID) => {
const response = await get(
`/${PLUGIN_ID}/config/custom-fields/${localCustomFieldUID}`
);
setCustomFieldConfig(response.data);
}, []);
const loadItems = useCallback(async () => {
if (!customFieldConfig) {
return;
}
setLoading(true);
if (!items || customFieldConfig.searchable) {
if (!props.disabled) {
const searchParams = new URLSearchParams();
if (customFieldConfig.searchable && debouncedFilter) {
searchParams.set("query", debouncedFilter);
}
const response = await get(
`/${PLUGIN_ID}/custom-fields/${customFieldUID}/items?${searchParams.toString()}`
);
if (field.value && !response.data.items.find((item) => item.value === field.value)) {
const responseItem = await get(
`/${PLUGIN_ID}/custom-fields/${customFieldUID}/item?value=${encodeURIComponent(field.value)}`
);
response.data.items.push(responseItem.data);
}
setItems(response.data.items);
} else if (field.value) {
const response = await get(
`/${PLUGIN_ID}/custom-fields/${customFieldUID}/item?value=${encodeURIComponent(field.value)}`
);
setItems([response.data]);
}
}
setLoading(false);
}, [
props.disabled,
customFieldConfig,
debouncedFilter
]);
useEffect(() => {
loadFieldConfig(customFieldUID).catch((error) => {
console.error(`Error fetching custom field config for CustomField[${customFieldUID}]:`, error);
});
}, [
loadFieldConfig,
customFieldUID
]);
useEffect(() => {
if (!customFieldConfig) {
return;
}
loadItems().catch((error) => {
console.error(`Error fetching items for CustomField[${customFieldUID}]:`, error);
});
}, [
loadItems,
customFieldConfig
]);
useEffect(() => {
if (field.value) {
setSelectedItem(items?.find((item) => item.value === field.value));
} else {
setSelectedItem(void 0);
}
}, [field.value, items]);
return /* @__PURE__ */ jsx(DesignSystemProvider, { theme, children: /* @__PURE__ */ jsxs(Field.Root, { disabled: props.disabled, required: props.required, hint: props.hint, name: props.name, id: props.name, error: field.error, children: [
/* @__PURE__ */ jsx(Field.Label, { children: props.label }),
/* @__PURE__ */ jsx(
Combobox,
{
onChange: (value) => field.onChange(props.name, value ?? ""),
value: field.value,
placeholder: props.placeholder,
disabled: props.disabled,
loading,
autocomplete: { type: "list", filter: "contains" },
onInputChange: (ev) => setFilter(ev.target.value),
filterValue: customFieldConfig?.searchable ? "" : void 0,
startIcon: selectedItem?.icon ? /* @__PURE__ */ jsx(Icon, { src: selectedItem.icon.src, alt: selectedItem.label, colorMask: selectedItem.icon.colorMask }) : null,
onClear: () => field.onChange(props.name, ""),
children: items?.map((item) => {
return /* @__PURE__ */ jsxs(
ComboboxOption,
{
value: item.value,
children: [
item.icon ? /* @__PURE__ */ jsx(Icon, { src: item.icon.src, alt: item.label, colorMask: item.icon.colorMask }) : null,
item.label
]
},
item.value
);
})
}
),
/* @__PURE__ */ jsx(Field.Hint, {}),
/* @__PURE__ */ jsx(Field.Error, {})
] }) });
};
export {
Input
};