UNPKG

sanity-plugin-computed-field

Version:

Sanity plugin that computes a field's value based on other fields or relationships with its document or external data. In other words, this field memoizes a value in a document using GROQ to lookup and custom javascript to compute the value from those GRO

139 lines (138 loc) 5.44 kB
import { jsxs, jsx } from "react/jsx-runtime"; import { Inline, Button, Spinner, ThemeProvider, Flex, Card, Container } from "@sanity/ui"; import React from "react"; import { useClient, useFormValue, set, defineType, definePlugin } from "sanity"; import { buildTheme } from "@sanity/ui/theme"; const useQueryReducer = ({ reduceQueryResult, documentQuerySelection, handleValueChange, value }) => { const [loading, setLoading] = React.useState(!1), client = useClient(), docId = useFormValue(["_id"]), _type = useFormValue(["_type"]), reducer = React.useCallback( (queryResult) => reduceQueryResult(queryResult), [reduceQueryResult] ); return { handleRegenerateValue: React.useCallback(async () => { const query = `*[_type == '${_type}' && _id == '${docId}' || _id == '${docId.replace( "drafts.", "" )}'] { _id, ${documentQuerySelection} }`; setLoading(!0); const items = await client.fetch(query), draft = items.find(({ _id }) => _id.includes("drafts")), published = items.find(({ _id }) => !_id.includes("drafts")), newValue = await Promise.resolve(reducer({ draft, published })); newValue !== value && handleValueChange(newValue), setLoading(!1); }, [_type, docId, documentQuerySelection, client, reducer, value, handleValueChange]), isRegenerating: loading }; }, theme = buildTheme(), InputControls = ({ buttonText, onClickButton, isLoading }) => /* @__PURE__ */ jsxs(Inline, { space: [2, 3], children: [ /* @__PURE__ */ jsx(Button, { onClick: onClickButton, title: buttonText, text: buttonText, mode: "ghost" }), isLoading && /* @__PURE__ */ jsx(Spinner, {}) ] }), ComputedBooleanInput = (props) => { const { schemaType, onChange, value } = props, { options } = schemaType, { reduceQueryResult, documentQuerySelection, buttonText = "Regenerate" } = options, handleValueChange = React.useCallback((val) => onChange(set(val)), [onChange]), { isRegenerating, handleRegenerateValue } = useQueryReducer({ reduceQueryResult, documentQuerySelection, handleValueChange, value }); return /* @__PURE__ */ jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", children: [ props.renderDefault(props), /* @__PURE__ */ jsx(Card, { marginLeft: [2, 3], children: /* @__PURE__ */ jsx( InputControls, { buttonText, isLoading: isRegenerating, onClickButton: handleRegenerateValue } ) }) ] }) }); }, ComputedNumberInput = (props) => { const { schemaType, onChange, value } = props, { options } = schemaType, { reduceQueryResult, documentQuerySelection, buttonText = "Regenerate" } = options, handleValueChange = React.useCallback((val) => onChange(set(val)), [onChange]), { isRegenerating, handleRegenerateValue } = useQueryReducer({ reduceQueryResult, documentQuerySelection, handleValueChange, value }); return /* @__PURE__ */ jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs(Inline, { space: [2], children: [ props.renderDefault(props), /* @__PURE__ */ jsx( InputControls, { isLoading: isRegenerating, onClickButton: handleRegenerateValue, buttonText } ) ] }) }); }, ComputedTextInput = (props) => { var _a; const { schemaType, onChange, value } = props, { options, type } = schemaType, { reduceQueryResult, documentQuerySelection, buttonText = "Regenerate" } = options, handleValueChange = React.useCallback((val) => onChange(set(val)), [onChange]), { isRegenerating, handleRegenerateValue } = useQueryReducer({ reduceQueryResult, documentQuerySelection, handleValueChange, value }), isString = ((_a = type == null ? void 0 : type.type) == null ? void 0 : _a.name) === "string"; return /* @__PURE__ */ jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs(Flex, { direction: isString ? "row" : "column", children: [ /* @__PURE__ */ jsx(Container, { flex: 1, children: props.renderDefault(props) }), /* @__PURE__ */ jsx(Card, { paddingLeft: isString ? 2 : 0, paddingTop: isString ? 0 : 2, children: /* @__PURE__ */ jsx( InputControls, { isLoading: isRegenerating, onClickButton: handleRegenerateValue, buttonText } ) }) ] }) }); }, computedBooleanSchema = defineType({ title: "Computed Boolean", type: "boolean", name: "computedBoolean", components: { input: ComputedBooleanInput } }), computedNumberSchema = defineType({ title: "Computed Number", type: "number", name: "computedNumber", components: { input: ComputedNumberInput } }), computedStringSchema = defineType({ title: "Computed String", type: "string", name: "computedString", components: { input: ComputedTextInput } }), computedTextSchema = defineType({ title: "Computed Text", type: "text", name: "computedText", components: { input: ComputedTextInput } }), sanityComputedField = definePlugin((config = {}) => ({ name: "sanity-plugin-computed-field", schema: { types: [ computedBooleanSchema, computedStringSchema, computedTextSchema, computedNumberSchema ] } })); export { ComputedBooleanInput, ComputedNumberInput, ComputedTextInput, computedBooleanSchema, computedNumberSchema, computedStringSchema, computedTextSchema, sanityComputedField }; //# sourceMappingURL=index.mjs.map