@madebywild/sanity-link-field 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var jsxRuntime = require("react/jsx-runtime"), sanityUtils = require("@madebywild/sanity-utils"), sanity = require("sanity"), asyncAutocomplete = require("@madebywild/sanity-utils/async-autocomplete"), ui = require("@sanity/ui"), changeCase = require("change-case"), React = require("react");
3
+ var jsxRuntime = require("react/jsx-runtime"), sanityUtils = require("@madebywild/sanity-utils"), sanity = require("sanity"), compilerRuntime = require("react/compiler-runtime"), asyncAutocomplete = require("@madebywild/sanity-utils/async-autocomplete"), ui = require("@sanity/ui"), changeCase = require("change-case"), React = require("react");
4
4
  function _interopNamespaceCompat(e) {
5
5
  if (e && typeof e == "object" && "default" in e) return e;
6
6
  var n = /* @__PURE__ */ Object.create(null);
@@ -18,8 +18,11 @@ function _interopNamespaceCompat(e) {
18
18
  }
19
19
  var changeCase__namespace = /* @__PURE__ */ _interopNamespaceCompat(changeCase), React__namespace = /* @__PURE__ */ _interopNamespaceCompat(React);
20
20
  function FieldInput(props) {
21
- const options = props.schemaType.options;
22
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 4, children: props.members.map((member) => member.kind !== "field" || options?.noCustomText && member.name === "customText" ? null : /* @__PURE__ */ jsxRuntime.jsx(sanity.MemberField, { member, ...props }, member.key)) });
21
+ const $ = compilerRuntime.c(5), options = props.schemaType.options;
22
+ let t0;
23
+ $[0] !== options?.noCustomText || $[1] !== props ? (t0 = props.members.map((member) => member.kind !== "field" || options?.noCustomText && member.name === "customText" ? null : /* @__PURE__ */ jsxRuntime.jsx(sanity.MemberField, { member, ...props }, member.key)), $[0] = options?.noCustomText, $[1] = props, $[2] = t0) : t0 = $[2];
24
+ let t1;
25
+ return $[3] !== t0 ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 4, children: t0 }), $[3] = t0, $[4] = t1) : t1 = $[4], t1;
23
26
  }
24
27
  const SectionsQuery = `
25
28
  *[_id == $pageId && defined(pageBuilder.sectionsArray)][0]{
@@ -34,24 +37,27 @@ function InternalLinkInput(props) {
34
37
  React__namespace.useEffect(() => {
35
38
  !selectedLink?._ref && selectedSection !== void 0 && props.onChange(sanity.unset(["sectionTarget"]));
36
39
  }, [selectedLink, selectedSection, props.onChange]);
37
- const client = sanity.useClient({ apiVersion: "2025-10-21" }), fetchSections = React__namespace.useCallback(() => selectedLink?._ref ? client.fetch(SectionsQuery, { pageId: selectedLink._ref }).catch(() => []) : [], [client, selectedLink, SectionsQuery]);
40
+ const client = sanity.useClient({
41
+ apiVersion: "2025-10-21"
42
+ }), fetchSections = React__namespace.useCallback(async () => {
43
+ if (!selectedLink?._ref) return [];
44
+ try {
45
+ return await client.fetch(SectionsQuery, {
46
+ pageId: selectedLink._ref
47
+ });
48
+ } catch {
49
+ return [];
50
+ }
51
+ }, [client, selectedLink?._ref]);
38
52
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
39
53
  linkFieldMember && /* @__PURE__ */ jsxRuntime.jsx(sanity.MemberField, { member: linkFieldMember, ...props }),
40
- /* @__PURE__ */ jsxRuntime.jsx(
41
- asyncAutocomplete.AsyncAutocomplete,
42
- {
43
- placeholder: "Select section",
44
- noOptionsPlaceholder: "No sections found",
45
- listItems: fetchSections,
46
- value: selectedSection,
47
- renderValue: (value, opt) => opt?.label ? changeCase__namespace.capitalCase(opt.label) : value,
48
- onChange: (value) => {
49
- const next = value ? sanity.set(value, ["sectionTarget"]) : sanity.unset(["sectionTarget"]);
50
- return props.onChange(next);
51
- },
52
- renderOption: ({ label, value }) => /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { as: "button", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 2, children: changeCase__namespace.capitalCase(label ?? value) }) }) })
53
- }
54
- )
54
+ selectedLink?._ref && /* @__PURE__ */ jsxRuntime.jsx(asyncAutocomplete.AsyncAutocomplete, { placeholder: "Select section", noOptionsPlaceholder: "No sections found", listItems: fetchSections, value: selectedSection, renderValue: (value, opt) => opt?.label ? changeCase__namespace.capitalCase(opt.label) : value, onChange: (value_0) => {
55
+ const next = value_0 ? sanity.set(value_0, ["sectionTarget"]) : sanity.unset(["sectionTarget"]);
56
+ return props.onChange(next);
57
+ }, renderOption: ({
58
+ label,
59
+ value: value_1
60
+ }) => /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { as: "button", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 2, children: changeCase__namespace.capitalCase(label ?? value_1) }) }) }) })
55
61
  ] });
56
62
  }
57
63
  function buildLinkPreview({
@@ -111,133 +117,134 @@ const typeName = "wild.link", LinkKind = {
111
117
  }, visibleIfKind = sanityUtils.visibleIf("kind"), requiredIfKind = sanityUtils.requiredIf("kind"), wildSanityLinkFieldPlugin = sanity.definePlugin((config) => ({
112
118
  name: "@madebywild/sanity-link-field",
113
119
  schema: {
114
- types: [
115
- sanity.defineType({
116
- name: typeName,
120
+ types: [sanity.defineType({
121
+ name: typeName,
122
+ type: "object",
123
+ title: "Link",
124
+ description: "Link to an internal page, external URL and more.",
125
+ icon: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u{1F517}" }),
126
+ components: {
127
+ input: (props) => /* @__PURE__ */ jsxRuntime.jsx(FieldInput, { ...props })
128
+ },
129
+ fields: [sanity.defineField({
130
+ name: "kind",
131
+ type: "string",
132
+ title: "Link Kind",
133
+ description: "Select the kind of link.",
134
+ validation: (R) => R.required().error("Select a link kind."),
135
+ options: {
136
+ layout: "radio",
137
+ direction: "horizontal",
138
+ list: [{
139
+ title: "\u{1F4C4} Internal",
140
+ value: LinkKind.internal
141
+ }, {
142
+ title: "\u{1F30D} External",
143
+ value: LinkKind.external
144
+ }, {
145
+ title: "\u{1F4E7} Email",
146
+ value: LinkKind.email
147
+ }, {
148
+ title: "\u260E\uFE0F Phone",
149
+ value: LinkKind.phone
150
+ }, {
151
+ title: "\u{1F4C3} File",
152
+ value: LinkKind.file
153
+ }]
154
+ }
155
+ }), sanity.defineField({
156
+ name: LinkKind.external,
157
+ type: "url",
158
+ title: "External Link",
159
+ ...visibleIfKind(LinkKind.external),
160
+ ...requiredIfKind(LinkKind.external)
161
+ }), sanity.defineField({
162
+ name: LinkKind.email,
163
+ type: "string",
164
+ title: "Email",
165
+ ...visibleIfKind(LinkKind.email),
166
+ ...requiredIfKind(LinkKind.email)
167
+ }), sanity.defineField({
168
+ name: LinkKind.phone,
169
+ type: "string",
170
+ title: "Phone",
171
+ ...visibleIfKind(LinkKind.phone),
172
+ ...requiredIfKind(LinkKind.phone)
173
+ }), sanity.defineField({
174
+ name: LinkKind.file,
175
+ type: "file",
176
+ title: "File",
177
+ ...visibleIfKind(LinkKind.file),
178
+ ...requiredIfKind(LinkKind.file)
179
+ }), sanity.defineField({
180
+ name: LinkKind.internal,
117
181
  type: "object",
118
- title: "Link",
119
- description: "Link to an internal page, external URL and more.",
120
- icon: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u{1F517}" }),
182
+ ...visibleIfKind(LinkKind.internal),
183
+ ...requiredIfKind(LinkKind.internal),
184
+ options: {
185
+ collapsed: !1,
186
+ collapsible: !1
187
+ },
121
188
  components: {
122
- input: (props) => /* @__PURE__ */ jsxRuntime.jsx(FieldInput, { ...props })
189
+ field: (props) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children }),
190
+ input: (props) => /* @__PURE__ */ jsxRuntime.jsx(InternalLinkInput, { ...props })
123
191
  },
124
- fields: [
125
- sanity.defineField({
126
- name: "kind",
127
- type: "string",
128
- title: "Link Kind",
129
- description: "Select the kind of link.",
130
- validation: (R) => R.required().error("Select a link kind."),
131
- options: {
132
- layout: "radio",
133
- direction: "horizontal",
134
- list: [
135
- { title: "\u{1F4C4} Internal", value: LinkKind.internal },
136
- { title: "\u{1F30D} External", value: LinkKind.external },
137
- { title: "\u{1F4E7} Email", value: LinkKind.email },
138
- { title: "\u260E\uFE0F Phone", value: LinkKind.phone },
139
- { title: "\u{1F4C3} File", value: LinkKind.file }
140
- ]
141
- }
142
- }),
143
- sanity.defineField({
144
- name: LinkKind.external,
145
- type: "url",
146
- title: "External Link",
147
- ...visibleIfKind(LinkKind.external),
148
- ...requiredIfKind(LinkKind.external)
149
- }),
150
- sanity.defineField({
151
- name: LinkKind.email,
152
- type: "string",
153
- title: "Email",
154
- ...visibleIfKind(LinkKind.email),
155
- ...requiredIfKind(LinkKind.email)
156
- }),
157
- sanity.defineField({
158
- name: LinkKind.phone,
159
- type: "string",
160
- title: "Phone",
161
- ...visibleIfKind(LinkKind.phone),
162
- ...requiredIfKind(LinkKind.phone)
163
- }),
164
- sanity.defineField({
165
- name: LinkKind.file,
166
- type: "file",
167
- title: "File",
168
- ...visibleIfKind(LinkKind.file),
169
- ...requiredIfKind(LinkKind.file)
170
- }),
171
- sanity.defineField({
172
- name: LinkKind.internal,
173
- type: "object",
174
- ...visibleIfKind(LinkKind.internal),
175
- ...requiredIfKind(LinkKind.internal),
176
- options: { collapsed: !1, collapsible: !1 },
177
- components: {
178
- field: (props) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children }),
179
- input: (props) => /* @__PURE__ */ jsxRuntime.jsx(InternalLinkInput, { ...props })
180
- },
181
- fields: [
182
- sanity.defineField({
183
- type: "reference",
184
- name: "link",
185
- title: "Internal Link",
186
- description: "Select a page and an optional section target.",
187
- weak: config.weakReferences ?? !0,
188
- to: config.internalLinkSchemaTypes,
189
- options: {
190
- disableNew: !0
191
- }
192
- }),
193
- sanity.defineField({
194
- type: "string",
195
- name: "sectionTarget",
196
- title: "Section Target"
197
- })
198
- ]
199
- }),
200
- sanity.defineField({
201
- name: "customText",
202
- type: "string",
203
- title: "Custom text",
204
- description: "Will take precedence over inferred text."
205
- }),
206
- sanity.defineField({
207
- name: "canDownload",
208
- type: "boolean",
209
- title: "Downloadable",
210
- initialValue: !0,
211
- description: "The file will be downloaded when the link is clicked.",
212
- options: { layout: "switch" },
213
- ...visibleIfKind(LinkKind.file),
214
- ...requiredIfKind(LinkKind.file)
215
- }),
216
- sanity.defineField({
217
- name: "openInNewTab",
218
- type: "boolean",
219
- title: "Open in new tab",
220
- description: "Open the link in a new tab.",
221
- initialValue: !1,
222
- options: { layout: "switch" },
223
- ...visibleIfKind([LinkKind.external, LinkKind.internal])
224
- })
225
- ],
226
- preview: {
227
- select: {
228
- kind: "kind",
229
- email: "email",
230
- phone: "phone",
231
- customText: "customText",
232
- fileName: "file.asset.originalFilename",
233
- externalUrl: "external",
234
- internalUri: "internal.uri.current",
235
- internalTitle: "internal.title"
236
- },
237
- prepare: (props) => buildLinkPreview(props)
238
- }
239
- })
240
- ]
192
+ fields: [sanity.defineField({
193
+ type: "reference",
194
+ name: "link",
195
+ title: "Internal Link",
196
+ description: "Select a page and an optional section target.",
197
+ weak: config.weakReferences ?? !0,
198
+ to: config.internalLinkSchemaTypes,
199
+ options: {
200
+ disableNew: !0
201
+ }
202
+ }), sanity.defineField({
203
+ type: "string",
204
+ name: "sectionTarget",
205
+ title: "Section Target"
206
+ })]
207
+ }), sanity.defineField({
208
+ name: "customText",
209
+ type: "string",
210
+ title: "Custom text",
211
+ description: "Will take precedence over inferred text."
212
+ }), sanity.defineField({
213
+ name: "canDownload",
214
+ type: "boolean",
215
+ title: "Downloadable",
216
+ initialValue: !0,
217
+ description: "The file will be downloaded when the link is clicked.",
218
+ options: {
219
+ layout: "switch"
220
+ },
221
+ ...visibleIfKind(LinkKind.file),
222
+ ...requiredIfKind(LinkKind.file)
223
+ }), sanity.defineField({
224
+ name: "openInNewTab",
225
+ type: "boolean",
226
+ title: "Open in new tab",
227
+ description: "Open the link in a new tab.",
228
+ initialValue: !1,
229
+ options: {
230
+ layout: "switch"
231
+ },
232
+ ...visibleIfKind([LinkKind.external, LinkKind.internal])
233
+ })],
234
+ preview: {
235
+ select: {
236
+ kind: "kind",
237
+ email: "email",
238
+ phone: "phone",
239
+ customText: "customText",
240
+ fileName: "file.asset.originalFilename",
241
+ externalUrl: "external",
242
+ internalUri: "internal.uri.current",
243
+ internalTitle: "internal.title"
244
+ },
245
+ prepare: (props) => buildLinkPreview(props)
246
+ }
247
+ })]
241
248
  }
242
249
  }));
243
250
  exports.LinkKind = LinkKind;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/input.tsx","../src/preview.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { useFieldMember } from \"@madebywild/sanity-utils\";\nimport { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Box, Card, Stack, Text } from \"@sanity/ui\";\nimport * as changeCase from \"change-case\";\nimport * as React from \"react\";\nimport type { ObjectInputProps, ObjectMember, Reference } from \"sanity\";\nimport { MemberField, set, unset, useClient } from \"sanity\";\nimport type { FieldOptions } from \"./types\";\n\nfunction FieldInput(props: ObjectInputProps) {\n const options = props.schemaType.options as FieldOptions | undefined;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n if (options?.noCustomText && member.name === \"customText\") return null;\n return <MemberField key={member.key} member={member} {...props} />;\n })}\n </Stack>\n );\n}\n\nconst SectionsQuery = `\n *[_id == $pageId && defined(pageBuilder.sectionsArray)][0]{\n \"sections\": array::compact(pageBuilder.sectionsArray[]{\n \"value\": _key,\n \"label\": coalesce(sectionSettings.sectionTitle, _type),\n }),\n }.sections\n`;\n\nfunction InternalLinkInput(props: ObjectInputProps) {\n const linkFieldMember = useFieldMember(props.members, \"link\");\n\n const selectedLink = props.value?.link as Reference | undefined;\n const selectedSection = props.value?.sectionTarget as string | undefined;\n\n // Reset sectionTarget if link is removed.\n React.useEffect(() => {\n if (!selectedLink?._ref && selectedSection !== undefined) {\n props.onChange(unset([\"sectionTarget\"]));\n }\n }, [selectedLink, selectedSection, props.onChange]);\n\n const client = useClient({ apiVersion: \"2025-10-21\" });\n\n const fetchSections = React.useCallback(() => {\n if (!selectedLink?._ref) return [];\n return client.fetch(SectionsQuery, { pageId: selectedLink._ref }).catch(() => []);\n }, [client, selectedLink, SectionsQuery]);\n\n return (\n <Stack space={2}>\n {linkFieldMember && <MemberField member={linkFieldMember} {...props} />}\n <AsyncAutocomplete\n placeholder=\"Select section\"\n noOptionsPlaceholder=\"No sections found\"\n listItems={fetchSections}\n value={selectedSection}\n renderValue={(value, opt) => {\n return opt?.label ? changeCase.capitalCase(opt.label) : value;\n }}\n onChange={(value) => {\n const next = value ? set(value, [\"sectionTarget\"]) : unset([\"sectionTarget\"]);\n return props.onChange(next);\n }}\n renderOption={({ label, value }) => {\n return (\n <Card as=\"button\">\n <Box flex={1} padding={3}>\n <Text size={2}>{changeCase.capitalCase(label ?? value)}</Text>\n </Box>\n </Card>\n );\n }}\n />\n </Stack>\n );\n}\n\nexport { FieldInput, InternalLinkInput };\n","import type { LinkKind } from \"./types\";\n\n/** @public */\nexport function buildLinkPreview({\n kind,\n email,\n phone,\n fileName,\n customText,\n internalUri,\n externalUrl,\n internalTitle,\n}: {\n kind?: string;\n email?: string;\n phone?: string;\n fileName?: string;\n customText?: string;\n externalUrl?: string;\n internalUri?: string;\n internalTitle?: string;\n}) {\n switch (kind as keyof typeof LinkKind) {\n case \"internal\": {\n return {\n title: customText ?? internalTitle ?? \"Internal Link\",\n subtitle: internalUri,\n media: () => <>📄</>,\n };\n }\n case \"external\":\n return {\n title: customText ?? \"External Link\",\n subtitle: externalUrl,\n media: () => <>🌍</>,\n };\n case \"email\":\n return {\n title: customText ?? \"Email Link\",\n subtitle: email,\n media: () => <>📧</>,\n };\n case \"phone\":\n return {\n title: customText ?? \"Phone Link\",\n subtitle: phone,\n media: () => <>☎️</>,\n };\n case \"file\":\n return {\n title: customText ?? \"File Link\",\n subtitle: fileName,\n media: () => <>📃</>,\n };\n default:\n return {\n title: customText ?? \"Empty Link\",\n media: () => <>⛓️‍💥</>,\n };\n }\n}\n","import type { ListItem } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { ObjectOptions, ReferenceTo, StringDefinition } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.link\" as const;\n\n/** @public */\nexport const LinkKind = {\n internal: \"internal\",\n external: \"external\",\n email: \"email\",\n phone: \"phone\",\n file: \"file\",\n} as const;\n\n/** @public */\nexport type SectionQueryResult = ListItem[];\n\n/** @public */\nexport type PluginConfig = {\n weakReferences?: boolean;\n internalLinkSchemaTypes: ReferenceTo;\n};\n\n/** @public */\nexport type FieldOptions = ObjectOptions & {\n noCustomText?: boolean;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<StringDefinition, \"type\" | \"fields\"> & {\n type: typeof typeName;\n };\n }\n}\n","import { requiredIf, visibleIf } from \"@madebywild/sanity-utils\";\nimport { defineField, definePlugin, defineType } from \"sanity\";\nimport { FieldInput, InternalLinkInput } from \"./input\";\nimport { buildLinkPreview } from \"./preview\";\nimport { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, typeName } from \"./types\";\n\nconst visibleIfKind = visibleIf(\"kind\");\nconst requiredIfKind = requiredIf(\"kind\");\n\n/** @public */\nconst wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-link-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Link\",\n description: \"Link to an internal page, external URL and more.\",\n icon: () => <>🔗</>,\n components: {\n input: (props) => <FieldInput {...props} />,\n },\n fields: [\n defineField({\n name: \"kind\",\n type: \"string\",\n title: \"Link Kind\",\n description: \"Select the kind of link.\",\n validation: (R) => R.required().error(\"Select a link kind.\"),\n options: {\n layout: \"radio\",\n direction: \"horizontal\",\n list: [\n { title: \"📄 Internal\", value: LinkKind.internal },\n { title: \"🌍 External\", value: LinkKind.external },\n { title: \"📧 Email\", value: LinkKind.email },\n { title: \"☎️ Phone\", value: LinkKind.phone },\n { title: \"📃 File\", value: LinkKind.file },\n ],\n },\n }),\n defineField({\n name: LinkKind.external,\n type: \"url\",\n title: \"External Link\",\n ...visibleIfKind(LinkKind.external),\n ...requiredIfKind(LinkKind.external),\n }),\n defineField({\n name: LinkKind.email,\n type: \"string\",\n title: \"Email\",\n ...visibleIfKind(LinkKind.email),\n ...requiredIfKind(LinkKind.email),\n }),\n defineField({\n name: LinkKind.phone,\n type: \"string\",\n title: \"Phone\",\n ...visibleIfKind(LinkKind.phone),\n ...requiredIfKind(LinkKind.phone),\n }),\n defineField({\n name: LinkKind.file,\n type: \"file\",\n title: \"File\",\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: LinkKind.internal,\n type: \"object\",\n ...visibleIfKind(LinkKind.internal),\n ...requiredIfKind(LinkKind.internal),\n options: { collapsed: false, collapsible: false },\n components: {\n field: (props) => <>{props.children}</>,\n input: (props) => <InternalLinkInput {...props} />,\n },\n fields: [\n defineField({\n type: \"reference\",\n name: \"link\",\n title: \"Internal Link\",\n description: \"Select a page and an optional section target.\",\n weak: config.weakReferences ?? true,\n to: config.internalLinkSchemaTypes,\n options: {\n disableNew: true,\n },\n }),\n defineField({\n type: \"string\",\n name: \"sectionTarget\",\n title: \"Section Target\",\n }),\n ],\n }),\n defineField({\n name: \"customText\",\n type: \"string\",\n title: \"Custom text\",\n description: \"Will take precedence over inferred text.\",\n }),\n defineField({\n name: \"canDownload\",\n type: \"boolean\",\n title: \"Downloadable\",\n initialValue: true,\n description: \"The file will be downloaded when the link is clicked.\",\n options: { layout: \"switch\" },\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: \"openInNewTab\",\n type: \"boolean\",\n title: \"Open in new tab\",\n description: \"Open the link in a new tab.\",\n initialValue: false,\n options: { layout: \"switch\" },\n ...visibleIfKind([LinkKind.external, LinkKind.internal]),\n }),\n ],\n preview: {\n select: {\n kind: \"kind\",\n email: \"email\",\n phone: \"phone\",\n customText: \"customText\",\n fileName: \"file.asset.originalFilename\",\n externalUrl: \"external\",\n internalUri: \"internal.uri.current\",\n internalTitle: \"internal.title\",\n },\n prepare: (props) => {\n return buildLinkPreview(props);\n },\n },\n }),\n ],\n },\n };\n});\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n buildLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["jsx","Stack","MemberField","useFieldMember","React","unset","useClient","jsxs","AsyncAutocomplete","changeCase","set","Card","Box","Text","Fragment","visibleIf","requiredIf","definePlugin","defineType","defineField"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/input.tsx","../src/preview.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { useFieldMember } from \"@madebywild/sanity-utils\";\nimport { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Box, Card, Stack, Text } from \"@sanity/ui\";\nimport * as changeCase from \"change-case\";\nimport * as React from \"react\";\nimport type { ObjectInputProps, ObjectMember, Reference } from \"sanity\";\nimport { MemberField, set, unset, useClient } from \"sanity\";\nimport type { FieldOptions } from \"./types\";\n\nfunction FieldInput(props: ObjectInputProps) {\n const options = props.schemaType.options as FieldOptions | undefined;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n if (options?.noCustomText && member.name === \"customText\") return null;\n return <MemberField key={member.key} member={member} {...props} />;\n })}\n </Stack>\n );\n}\n\nconst SectionsQuery = `\n *[_id == $pageId && defined(pageBuilder.sectionsArray)][0]{\n \"sections\": array::compact(pageBuilder.sectionsArray[]{\n \"value\": _key,\n \"label\": coalesce(sectionSettings.sectionTitle, _type),\n }),\n }.sections\n`;\n\nfunction InternalLinkInput(props: ObjectInputProps) {\n const linkFieldMember = useFieldMember(props.members, \"link\");\n\n const selectedLink = props.value?.link as Reference | undefined;\n const selectedSection = props.value?.sectionTarget as string | undefined;\n\n // Reset sectionTarget if link is removed.\n React.useEffect(() => {\n if (!selectedLink?._ref && selectedSection !== undefined) {\n props.onChange(unset([\"sectionTarget\"]));\n }\n }, [selectedLink, selectedSection, props.onChange]);\n\n const client = useClient({ apiVersion: \"2025-10-21\" });\n\n const fetchSections = React.useCallback(async () => {\n if (!selectedLink?._ref) return [];\n\n try {\n const items = await client.fetch(SectionsQuery, { pageId: selectedLink._ref });\n return items;\n } catch {\n return [];\n }\n }, [client, selectedLink?._ref]);\n\n return (\n <Stack space={2}>\n {linkFieldMember && <MemberField member={linkFieldMember} {...props} />}\n {selectedLink?._ref && (\n <AsyncAutocomplete\n placeholder=\"Select section\"\n noOptionsPlaceholder=\"No sections found\"\n listItems={fetchSections}\n value={selectedSection}\n renderValue={(value, opt) => {\n return opt?.label ? changeCase.capitalCase(opt.label) : value;\n }}\n onChange={(value) => {\n const next = value ? set(value, [\"sectionTarget\"]) : unset([\"sectionTarget\"]);\n return props.onChange(next);\n }}\n renderOption={({ label, value }) => {\n return (\n <Card as=\"button\">\n <Box flex={1} padding={3}>\n <Text size={2}>{changeCase.capitalCase(label ?? value)}</Text>\n </Box>\n </Card>\n );\n }}\n />\n )}\n </Stack>\n );\n}\n\nexport { FieldInput, InternalLinkInput };\n","import type { LinkKind } from \"./types\";\n\n/** @public */\nexport function buildLinkPreview({\n kind,\n email,\n phone,\n fileName,\n customText,\n internalUri,\n externalUrl,\n internalTitle,\n}: {\n kind?: string;\n email?: string;\n phone?: string;\n fileName?: string;\n customText?: string;\n externalUrl?: string;\n internalUri?: string;\n internalTitle?: string;\n}) {\n switch (kind as keyof typeof LinkKind) {\n case \"internal\": {\n return {\n title: customText ?? internalTitle ?? \"Internal Link\",\n subtitle: internalUri,\n media: () => <>📄</>,\n };\n }\n case \"external\":\n return {\n title: customText ?? \"External Link\",\n subtitle: externalUrl,\n media: () => <>🌍</>,\n };\n case \"email\":\n return {\n title: customText ?? \"Email Link\",\n subtitle: email,\n media: () => <>📧</>,\n };\n case \"phone\":\n return {\n title: customText ?? \"Phone Link\",\n subtitle: phone,\n media: () => <>☎️</>,\n };\n case \"file\":\n return {\n title: customText ?? \"File Link\",\n subtitle: fileName,\n media: () => <>📃</>,\n };\n default:\n return {\n title: customText ?? \"Empty Link\",\n media: () => <>⛓️‍💥</>,\n };\n }\n}\n","import type { ListItem } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { ObjectDefinition, ObjectOptions, ReferenceTo } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.link\" as const;\n\n/** @public */\nexport const LinkKind = {\n internal: \"internal\",\n external: \"external\",\n email: \"email\",\n phone: \"phone\",\n file: \"file\",\n} as const;\n\n/** @public */\nexport type SectionQueryResult = ListItem[];\n\n/** @public */\nexport type PluginConfig = {\n weakReferences?: boolean;\n internalLinkSchemaTypes: ReferenceTo;\n};\n\n/** @public */\nexport type FieldOptions = ObjectOptions & {\n noCustomText?: boolean;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<ObjectDefinition, \"type\" | \"fields\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n","import { requiredIf, visibleIf } from \"@madebywild/sanity-utils\";\nimport { defineField, definePlugin, defineType } from \"sanity\";\nimport { FieldInput, InternalLinkInput } from \"./input\";\nimport { buildLinkPreview } from \"./preview\";\nimport { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, typeName } from \"./types\";\n\nconst visibleIfKind = visibleIf(\"kind\");\nconst requiredIfKind = requiredIf(\"kind\");\n\n/** @public */\nconst wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-link-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Link\",\n description: \"Link to an internal page, external URL and more.\",\n icon: () => <>🔗</>,\n components: {\n input: (props) => <FieldInput {...props} />,\n },\n fields: [\n defineField({\n name: \"kind\",\n type: \"string\",\n title: \"Link Kind\",\n description: \"Select the kind of link.\",\n validation: (R) => R.required().error(\"Select a link kind.\"),\n options: {\n layout: \"radio\",\n direction: \"horizontal\",\n list: [\n { title: \"📄 Internal\", value: LinkKind.internal },\n { title: \"🌍 External\", value: LinkKind.external },\n { title: \"📧 Email\", value: LinkKind.email },\n { title: \"☎️ Phone\", value: LinkKind.phone },\n { title: \"📃 File\", value: LinkKind.file },\n ],\n },\n }),\n defineField({\n name: LinkKind.external,\n type: \"url\",\n title: \"External Link\",\n ...visibleIfKind(LinkKind.external),\n ...requiredIfKind(LinkKind.external),\n }),\n defineField({\n name: LinkKind.email,\n type: \"string\",\n title: \"Email\",\n ...visibleIfKind(LinkKind.email),\n ...requiredIfKind(LinkKind.email),\n }),\n defineField({\n name: LinkKind.phone,\n type: \"string\",\n title: \"Phone\",\n ...visibleIfKind(LinkKind.phone),\n ...requiredIfKind(LinkKind.phone),\n }),\n defineField({\n name: LinkKind.file,\n type: \"file\",\n title: \"File\",\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: LinkKind.internal,\n type: \"object\",\n ...visibleIfKind(LinkKind.internal),\n ...requiredIfKind(LinkKind.internal),\n options: { collapsed: false, collapsible: false },\n components: {\n field: (props) => <>{props.children}</>,\n input: (props) => <InternalLinkInput {...props} />,\n },\n fields: [\n defineField({\n type: \"reference\",\n name: \"link\",\n title: \"Internal Link\",\n description: \"Select a page and an optional section target.\",\n weak: config.weakReferences ?? true,\n to: config.internalLinkSchemaTypes,\n options: {\n disableNew: true,\n },\n }),\n defineField({\n type: \"string\",\n name: \"sectionTarget\",\n title: \"Section Target\",\n }),\n ],\n }),\n defineField({\n name: \"customText\",\n type: \"string\",\n title: \"Custom text\",\n description: \"Will take precedence over inferred text.\",\n }),\n defineField({\n name: \"canDownload\",\n type: \"boolean\",\n title: \"Downloadable\",\n initialValue: true,\n description: \"The file will be downloaded when the link is clicked.\",\n options: { layout: \"switch\" },\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: \"openInNewTab\",\n type: \"boolean\",\n title: \"Open in new tab\",\n description: \"Open the link in a new tab.\",\n initialValue: false,\n options: { layout: \"switch\" },\n ...visibleIfKind([LinkKind.external, LinkKind.internal]),\n }),\n ],\n preview: {\n select: {\n kind: \"kind\",\n email: \"email\",\n phone: \"phone\",\n customText: \"customText\",\n fileName: \"file.asset.originalFilename\",\n externalUrl: \"external\",\n internalUri: \"internal.uri.current\",\n internalTitle: \"internal.title\",\n },\n prepare: (props) => {\n return buildLinkPreview(props);\n },\n },\n }),\n ],\n },\n };\n});\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n buildLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["FieldInput","props","$","_c","options","schemaType","t0","noCustomText","members","map","member","kind","name","MemberField","key","t1","jsx","Stack","SectionsQuery","InternalLinkInput","linkFieldMember","useFieldMember","selectedLink","value","link","selectedSection","sectionTarget","React","useEffect","_ref","undefined","onChange","unset","client","useClient","apiVersion","fetchSections","useCallback","fetch","pageId","jsxs","AsyncAutocomplete","opt","label","changeCase","capitalCase","next","set","Card","Box","Text","buildLinkPreview","email","phone","fileName","customText","internalUri","externalUrl","internalTitle","title","subtitle","media","Fragment","typeName","LinkKind","internal","external","file","visibleIfKind","visibleIf","requiredIfKind","requiredIf","wildSanityLinkFieldPlugin","definePlugin","config","schema","types","defineType","type","description","icon","components","input","fields","defineField","validation","R","required","error","layout","direction","list","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as sanity0 from "sanity";
2
- import { ObjectOptions, ReferenceTo, StringDefinition } from "sanity";
2
+ import { ObjectDefinition, ObjectOptions, ReferenceTo } from "sanity";
3
3
  import * as react1 from "react";
4
4
  /** @public */
5
5
  declare function buildLinkPreview({
@@ -58,8 +58,9 @@ type FieldOptions = ObjectOptions & {
58
58
  };
59
59
  declare module "sanity" {
60
60
  interface IntrinsicDefinitions {
61
- [typeName]: Omit<StringDefinition, "type" | "fields"> & {
61
+ [typeName]: Omit<ObjectDefinition, "type" | "fields" | "options"> & {
62
62
  type: typeof typeName;
63
+ options?: FieldOptions;
63
64
  };
64
65
  }
65
66
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as sanity0 from "sanity";
2
- import { ObjectOptions, ReferenceTo, StringDefinition } from "sanity";
2
+ import { ObjectDefinition, ObjectOptions, ReferenceTo } from "sanity";
3
3
  import * as react1 from "react";
4
4
  /** @public */
5
5
  declare function buildLinkPreview({
@@ -58,8 +58,9 @@ type FieldOptions = ObjectOptions & {
58
58
  };
59
59
  declare module "sanity" {
60
60
  interface IntrinsicDefinitions {
61
- [typeName]: Omit<StringDefinition, "type" | "fields"> & {
61
+ [typeName]: Omit<ObjectDefinition, "type" | "fields" | "options"> & {
62
62
  type: typeof typeName;
63
+ options?: FieldOptions;
63
64
  };
64
65
  }
65
66
  }
package/dist/index.js CHANGED
@@ -1,13 +1,17 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useFieldMember, visibleIf, requiredIf } from "@madebywild/sanity-utils";
3
3
  import { unset, useClient, MemberField, set, definePlugin, defineType, defineField } from "sanity";
4
+ import { c } from "react/compiler-runtime";
4
5
  import { AsyncAutocomplete } from "@madebywild/sanity-utils/async-autocomplete";
5
6
  import { Stack, Card, Box, Text } from "@sanity/ui";
6
7
  import * as changeCase from "change-case";
7
8
  import * as React from "react";
8
9
  function FieldInput(props) {
9
- const options = props.schemaType.options;
10
- return /* @__PURE__ */ jsx(Stack, { space: 4, children: props.members.map((member) => member.kind !== "field" || options?.noCustomText && member.name === "customText" ? null : /* @__PURE__ */ jsx(MemberField, { member, ...props }, member.key)) });
10
+ const $ = c(5), options = props.schemaType.options;
11
+ let t0;
12
+ $[0] !== options?.noCustomText || $[1] !== props ? (t0 = props.members.map((member) => member.kind !== "field" || options?.noCustomText && member.name === "customText" ? null : /* @__PURE__ */ jsx(MemberField, { member, ...props }, member.key)), $[0] = options?.noCustomText, $[1] = props, $[2] = t0) : t0 = $[2];
13
+ let t1;
14
+ return $[3] !== t0 ? (t1 = /* @__PURE__ */ jsx(Stack, { space: 4, children: t0 }), $[3] = t0, $[4] = t1) : t1 = $[4], t1;
11
15
  }
12
16
  const SectionsQuery = `
13
17
  *[_id == $pageId && defined(pageBuilder.sectionsArray)][0]{
@@ -22,24 +26,27 @@ function InternalLinkInput(props) {
22
26
  React.useEffect(() => {
23
27
  !selectedLink?._ref && selectedSection !== void 0 && props.onChange(unset(["sectionTarget"]));
24
28
  }, [selectedLink, selectedSection, props.onChange]);
25
- const client = useClient({ apiVersion: "2025-10-21" }), fetchSections = React.useCallback(() => selectedLink?._ref ? client.fetch(SectionsQuery, { pageId: selectedLink._ref }).catch(() => []) : [], [client, selectedLink, SectionsQuery]);
29
+ const client = useClient({
30
+ apiVersion: "2025-10-21"
31
+ }), fetchSections = React.useCallback(async () => {
32
+ if (!selectedLink?._ref) return [];
33
+ try {
34
+ return await client.fetch(SectionsQuery, {
35
+ pageId: selectedLink._ref
36
+ });
37
+ } catch {
38
+ return [];
39
+ }
40
+ }, [client, selectedLink?._ref]);
26
41
  return /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
27
42
  linkFieldMember && /* @__PURE__ */ jsx(MemberField, { member: linkFieldMember, ...props }),
28
- /* @__PURE__ */ jsx(
29
- AsyncAutocomplete,
30
- {
31
- placeholder: "Select section",
32
- noOptionsPlaceholder: "No sections found",
33
- listItems: fetchSections,
34
- value: selectedSection,
35
- renderValue: (value, opt) => opt?.label ? changeCase.capitalCase(opt.label) : value,
36
- onChange: (value) => {
37
- const next = value ? set(value, ["sectionTarget"]) : unset(["sectionTarget"]);
38
- return props.onChange(next);
39
- },
40
- renderOption: ({ label, value }) => /* @__PURE__ */ jsx(Card, { as: "button", children: /* @__PURE__ */ jsx(Box, { flex: 1, padding: 3, children: /* @__PURE__ */ jsx(Text, { size: 2, children: changeCase.capitalCase(label ?? value) }) }) })
41
- }
42
- )
43
+ selectedLink?._ref && /* @__PURE__ */ jsx(AsyncAutocomplete, { placeholder: "Select section", noOptionsPlaceholder: "No sections found", listItems: fetchSections, value: selectedSection, renderValue: (value, opt) => opt?.label ? changeCase.capitalCase(opt.label) : value, onChange: (value_0) => {
44
+ const next = value_0 ? set(value_0, ["sectionTarget"]) : unset(["sectionTarget"]);
45
+ return props.onChange(next);
46
+ }, renderOption: ({
47
+ label,
48
+ value: value_1
49
+ }) => /* @__PURE__ */ jsx(Card, { as: "button", children: /* @__PURE__ */ jsx(Box, { flex: 1, padding: 3, children: /* @__PURE__ */ jsx(Text, { size: 2, children: changeCase.capitalCase(label ?? value_1) }) }) }) })
43
50
  ] });
44
51
  }
45
52
  function buildLinkPreview({
@@ -99,133 +106,134 @@ const typeName = "wild.link", LinkKind = {
99
106
  }, visibleIfKind = visibleIf("kind"), requiredIfKind = requiredIf("kind"), wildSanityLinkFieldPlugin = definePlugin((config) => ({
100
107
  name: "@madebywild/sanity-link-field",
101
108
  schema: {
102
- types: [
103
- defineType({
104
- name: typeName,
109
+ types: [defineType({
110
+ name: typeName,
111
+ type: "object",
112
+ title: "Link",
113
+ description: "Link to an internal page, external URL and more.",
114
+ icon: () => /* @__PURE__ */ jsx(Fragment, { children: "\u{1F517}" }),
115
+ components: {
116
+ input: (props) => /* @__PURE__ */ jsx(FieldInput, { ...props })
117
+ },
118
+ fields: [defineField({
119
+ name: "kind",
120
+ type: "string",
121
+ title: "Link Kind",
122
+ description: "Select the kind of link.",
123
+ validation: (R) => R.required().error("Select a link kind."),
124
+ options: {
125
+ layout: "radio",
126
+ direction: "horizontal",
127
+ list: [{
128
+ title: "\u{1F4C4} Internal",
129
+ value: LinkKind.internal
130
+ }, {
131
+ title: "\u{1F30D} External",
132
+ value: LinkKind.external
133
+ }, {
134
+ title: "\u{1F4E7} Email",
135
+ value: LinkKind.email
136
+ }, {
137
+ title: "\u260E\uFE0F Phone",
138
+ value: LinkKind.phone
139
+ }, {
140
+ title: "\u{1F4C3} File",
141
+ value: LinkKind.file
142
+ }]
143
+ }
144
+ }), defineField({
145
+ name: LinkKind.external,
146
+ type: "url",
147
+ title: "External Link",
148
+ ...visibleIfKind(LinkKind.external),
149
+ ...requiredIfKind(LinkKind.external)
150
+ }), defineField({
151
+ name: LinkKind.email,
152
+ type: "string",
153
+ title: "Email",
154
+ ...visibleIfKind(LinkKind.email),
155
+ ...requiredIfKind(LinkKind.email)
156
+ }), defineField({
157
+ name: LinkKind.phone,
158
+ type: "string",
159
+ title: "Phone",
160
+ ...visibleIfKind(LinkKind.phone),
161
+ ...requiredIfKind(LinkKind.phone)
162
+ }), defineField({
163
+ name: LinkKind.file,
164
+ type: "file",
165
+ title: "File",
166
+ ...visibleIfKind(LinkKind.file),
167
+ ...requiredIfKind(LinkKind.file)
168
+ }), defineField({
169
+ name: LinkKind.internal,
105
170
  type: "object",
106
- title: "Link",
107
- description: "Link to an internal page, external URL and more.",
108
- icon: () => /* @__PURE__ */ jsx(Fragment, { children: "\u{1F517}" }),
171
+ ...visibleIfKind(LinkKind.internal),
172
+ ...requiredIfKind(LinkKind.internal),
173
+ options: {
174
+ collapsed: !1,
175
+ collapsible: !1
176
+ },
109
177
  components: {
110
- input: (props) => /* @__PURE__ */ jsx(FieldInput, { ...props })
178
+ field: (props) => /* @__PURE__ */ jsx(Fragment, { children: props.children }),
179
+ input: (props) => /* @__PURE__ */ jsx(InternalLinkInput, { ...props })
111
180
  },
112
- fields: [
113
- defineField({
114
- name: "kind",
115
- type: "string",
116
- title: "Link Kind",
117
- description: "Select the kind of link.",
118
- validation: (R) => R.required().error("Select a link kind."),
119
- options: {
120
- layout: "radio",
121
- direction: "horizontal",
122
- list: [
123
- { title: "\u{1F4C4} Internal", value: LinkKind.internal },
124
- { title: "\u{1F30D} External", value: LinkKind.external },
125
- { title: "\u{1F4E7} Email", value: LinkKind.email },
126
- { title: "\u260E\uFE0F Phone", value: LinkKind.phone },
127
- { title: "\u{1F4C3} File", value: LinkKind.file }
128
- ]
129
- }
130
- }),
131
- defineField({
132
- name: LinkKind.external,
133
- type: "url",
134
- title: "External Link",
135
- ...visibleIfKind(LinkKind.external),
136
- ...requiredIfKind(LinkKind.external)
137
- }),
138
- defineField({
139
- name: LinkKind.email,
140
- type: "string",
141
- title: "Email",
142
- ...visibleIfKind(LinkKind.email),
143
- ...requiredIfKind(LinkKind.email)
144
- }),
145
- defineField({
146
- name: LinkKind.phone,
147
- type: "string",
148
- title: "Phone",
149
- ...visibleIfKind(LinkKind.phone),
150
- ...requiredIfKind(LinkKind.phone)
151
- }),
152
- defineField({
153
- name: LinkKind.file,
154
- type: "file",
155
- title: "File",
156
- ...visibleIfKind(LinkKind.file),
157
- ...requiredIfKind(LinkKind.file)
158
- }),
159
- defineField({
160
- name: LinkKind.internal,
161
- type: "object",
162
- ...visibleIfKind(LinkKind.internal),
163
- ...requiredIfKind(LinkKind.internal),
164
- options: { collapsed: !1, collapsible: !1 },
165
- components: {
166
- field: (props) => /* @__PURE__ */ jsx(Fragment, { children: props.children }),
167
- input: (props) => /* @__PURE__ */ jsx(InternalLinkInput, { ...props })
168
- },
169
- fields: [
170
- defineField({
171
- type: "reference",
172
- name: "link",
173
- title: "Internal Link",
174
- description: "Select a page and an optional section target.",
175
- weak: config.weakReferences ?? !0,
176
- to: config.internalLinkSchemaTypes,
177
- options: {
178
- disableNew: !0
179
- }
180
- }),
181
- defineField({
182
- type: "string",
183
- name: "sectionTarget",
184
- title: "Section Target"
185
- })
186
- ]
187
- }),
188
- defineField({
189
- name: "customText",
190
- type: "string",
191
- title: "Custom text",
192
- description: "Will take precedence over inferred text."
193
- }),
194
- defineField({
195
- name: "canDownload",
196
- type: "boolean",
197
- title: "Downloadable",
198
- initialValue: !0,
199
- description: "The file will be downloaded when the link is clicked.",
200
- options: { layout: "switch" },
201
- ...visibleIfKind(LinkKind.file),
202
- ...requiredIfKind(LinkKind.file)
203
- }),
204
- defineField({
205
- name: "openInNewTab",
206
- type: "boolean",
207
- title: "Open in new tab",
208
- description: "Open the link in a new tab.",
209
- initialValue: !1,
210
- options: { layout: "switch" },
211
- ...visibleIfKind([LinkKind.external, LinkKind.internal])
212
- })
213
- ],
214
- preview: {
215
- select: {
216
- kind: "kind",
217
- email: "email",
218
- phone: "phone",
219
- customText: "customText",
220
- fileName: "file.asset.originalFilename",
221
- externalUrl: "external",
222
- internalUri: "internal.uri.current",
223
- internalTitle: "internal.title"
224
- },
225
- prepare: (props) => buildLinkPreview(props)
226
- }
227
- })
228
- ]
181
+ fields: [defineField({
182
+ type: "reference",
183
+ name: "link",
184
+ title: "Internal Link",
185
+ description: "Select a page and an optional section target.",
186
+ weak: config.weakReferences ?? !0,
187
+ to: config.internalLinkSchemaTypes,
188
+ options: {
189
+ disableNew: !0
190
+ }
191
+ }), defineField({
192
+ type: "string",
193
+ name: "sectionTarget",
194
+ title: "Section Target"
195
+ })]
196
+ }), defineField({
197
+ name: "customText",
198
+ type: "string",
199
+ title: "Custom text",
200
+ description: "Will take precedence over inferred text."
201
+ }), defineField({
202
+ name: "canDownload",
203
+ type: "boolean",
204
+ title: "Downloadable",
205
+ initialValue: !0,
206
+ description: "The file will be downloaded when the link is clicked.",
207
+ options: {
208
+ layout: "switch"
209
+ },
210
+ ...visibleIfKind(LinkKind.file),
211
+ ...requiredIfKind(LinkKind.file)
212
+ }), defineField({
213
+ name: "openInNewTab",
214
+ type: "boolean",
215
+ title: "Open in new tab",
216
+ description: "Open the link in a new tab.",
217
+ initialValue: !1,
218
+ options: {
219
+ layout: "switch"
220
+ },
221
+ ...visibleIfKind([LinkKind.external, LinkKind.internal])
222
+ })],
223
+ preview: {
224
+ select: {
225
+ kind: "kind",
226
+ email: "email",
227
+ phone: "phone",
228
+ customText: "customText",
229
+ fileName: "file.asset.originalFilename",
230
+ externalUrl: "external",
231
+ internalUri: "internal.uri.current",
232
+ internalTitle: "internal.title"
233
+ },
234
+ prepare: (props) => buildLinkPreview(props)
235
+ }
236
+ })]
229
237
  }
230
238
  }));
231
239
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/input.tsx","../src/preview.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { useFieldMember } from \"@madebywild/sanity-utils\";\nimport { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Box, Card, Stack, Text } from \"@sanity/ui\";\nimport * as changeCase from \"change-case\";\nimport * as React from \"react\";\nimport type { ObjectInputProps, ObjectMember, Reference } from \"sanity\";\nimport { MemberField, set, unset, useClient } from \"sanity\";\nimport type { FieldOptions } from \"./types\";\n\nfunction FieldInput(props: ObjectInputProps) {\n const options = props.schemaType.options as FieldOptions | undefined;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n if (options?.noCustomText && member.name === \"customText\") return null;\n return <MemberField key={member.key} member={member} {...props} />;\n })}\n </Stack>\n );\n}\n\nconst SectionsQuery = `\n *[_id == $pageId && defined(pageBuilder.sectionsArray)][0]{\n \"sections\": array::compact(pageBuilder.sectionsArray[]{\n \"value\": _key,\n \"label\": coalesce(sectionSettings.sectionTitle, _type),\n }),\n }.sections\n`;\n\nfunction InternalLinkInput(props: ObjectInputProps) {\n const linkFieldMember = useFieldMember(props.members, \"link\");\n\n const selectedLink = props.value?.link as Reference | undefined;\n const selectedSection = props.value?.sectionTarget as string | undefined;\n\n // Reset sectionTarget if link is removed.\n React.useEffect(() => {\n if (!selectedLink?._ref && selectedSection !== undefined) {\n props.onChange(unset([\"sectionTarget\"]));\n }\n }, [selectedLink, selectedSection, props.onChange]);\n\n const client = useClient({ apiVersion: \"2025-10-21\" });\n\n const fetchSections = React.useCallback(() => {\n if (!selectedLink?._ref) return [];\n return client.fetch(SectionsQuery, { pageId: selectedLink._ref }).catch(() => []);\n }, [client, selectedLink, SectionsQuery]);\n\n return (\n <Stack space={2}>\n {linkFieldMember && <MemberField member={linkFieldMember} {...props} />}\n <AsyncAutocomplete\n placeholder=\"Select section\"\n noOptionsPlaceholder=\"No sections found\"\n listItems={fetchSections}\n value={selectedSection}\n renderValue={(value, opt) => {\n return opt?.label ? changeCase.capitalCase(opt.label) : value;\n }}\n onChange={(value) => {\n const next = value ? set(value, [\"sectionTarget\"]) : unset([\"sectionTarget\"]);\n return props.onChange(next);\n }}\n renderOption={({ label, value }) => {\n return (\n <Card as=\"button\">\n <Box flex={1} padding={3}>\n <Text size={2}>{changeCase.capitalCase(label ?? value)}</Text>\n </Box>\n </Card>\n );\n }}\n />\n </Stack>\n );\n}\n\nexport { FieldInput, InternalLinkInput };\n","import type { LinkKind } from \"./types\";\n\n/** @public */\nexport function buildLinkPreview({\n kind,\n email,\n phone,\n fileName,\n customText,\n internalUri,\n externalUrl,\n internalTitle,\n}: {\n kind?: string;\n email?: string;\n phone?: string;\n fileName?: string;\n customText?: string;\n externalUrl?: string;\n internalUri?: string;\n internalTitle?: string;\n}) {\n switch (kind as keyof typeof LinkKind) {\n case \"internal\": {\n return {\n title: customText ?? internalTitle ?? \"Internal Link\",\n subtitle: internalUri,\n media: () => <>📄</>,\n };\n }\n case \"external\":\n return {\n title: customText ?? \"External Link\",\n subtitle: externalUrl,\n media: () => <>🌍</>,\n };\n case \"email\":\n return {\n title: customText ?? \"Email Link\",\n subtitle: email,\n media: () => <>📧</>,\n };\n case \"phone\":\n return {\n title: customText ?? \"Phone Link\",\n subtitle: phone,\n media: () => <>☎️</>,\n };\n case \"file\":\n return {\n title: customText ?? \"File Link\",\n subtitle: fileName,\n media: () => <>📃</>,\n };\n default:\n return {\n title: customText ?? \"Empty Link\",\n media: () => <>⛓️‍💥</>,\n };\n }\n}\n","import type { ListItem } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { ObjectOptions, ReferenceTo, StringDefinition } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.link\" as const;\n\n/** @public */\nexport const LinkKind = {\n internal: \"internal\",\n external: \"external\",\n email: \"email\",\n phone: \"phone\",\n file: \"file\",\n} as const;\n\n/** @public */\nexport type SectionQueryResult = ListItem[];\n\n/** @public */\nexport type PluginConfig = {\n weakReferences?: boolean;\n internalLinkSchemaTypes: ReferenceTo;\n};\n\n/** @public */\nexport type FieldOptions = ObjectOptions & {\n noCustomText?: boolean;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<StringDefinition, \"type\" | \"fields\"> & {\n type: typeof typeName;\n };\n }\n}\n","import { requiredIf, visibleIf } from \"@madebywild/sanity-utils\";\nimport { defineField, definePlugin, defineType } from \"sanity\";\nimport { FieldInput, InternalLinkInput } from \"./input\";\nimport { buildLinkPreview } from \"./preview\";\nimport { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, typeName } from \"./types\";\n\nconst visibleIfKind = visibleIf(\"kind\");\nconst requiredIfKind = requiredIf(\"kind\");\n\n/** @public */\nconst wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-link-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Link\",\n description: \"Link to an internal page, external URL and more.\",\n icon: () => <>🔗</>,\n components: {\n input: (props) => <FieldInput {...props} />,\n },\n fields: [\n defineField({\n name: \"kind\",\n type: \"string\",\n title: \"Link Kind\",\n description: \"Select the kind of link.\",\n validation: (R) => R.required().error(\"Select a link kind.\"),\n options: {\n layout: \"radio\",\n direction: \"horizontal\",\n list: [\n { title: \"📄 Internal\", value: LinkKind.internal },\n { title: \"🌍 External\", value: LinkKind.external },\n { title: \"📧 Email\", value: LinkKind.email },\n { title: \"☎️ Phone\", value: LinkKind.phone },\n { title: \"📃 File\", value: LinkKind.file },\n ],\n },\n }),\n defineField({\n name: LinkKind.external,\n type: \"url\",\n title: \"External Link\",\n ...visibleIfKind(LinkKind.external),\n ...requiredIfKind(LinkKind.external),\n }),\n defineField({\n name: LinkKind.email,\n type: \"string\",\n title: \"Email\",\n ...visibleIfKind(LinkKind.email),\n ...requiredIfKind(LinkKind.email),\n }),\n defineField({\n name: LinkKind.phone,\n type: \"string\",\n title: \"Phone\",\n ...visibleIfKind(LinkKind.phone),\n ...requiredIfKind(LinkKind.phone),\n }),\n defineField({\n name: LinkKind.file,\n type: \"file\",\n title: \"File\",\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: LinkKind.internal,\n type: \"object\",\n ...visibleIfKind(LinkKind.internal),\n ...requiredIfKind(LinkKind.internal),\n options: { collapsed: false, collapsible: false },\n components: {\n field: (props) => <>{props.children}</>,\n input: (props) => <InternalLinkInput {...props} />,\n },\n fields: [\n defineField({\n type: \"reference\",\n name: \"link\",\n title: \"Internal Link\",\n description: \"Select a page and an optional section target.\",\n weak: config.weakReferences ?? true,\n to: config.internalLinkSchemaTypes,\n options: {\n disableNew: true,\n },\n }),\n defineField({\n type: \"string\",\n name: \"sectionTarget\",\n title: \"Section Target\",\n }),\n ],\n }),\n defineField({\n name: \"customText\",\n type: \"string\",\n title: \"Custom text\",\n description: \"Will take precedence over inferred text.\",\n }),\n defineField({\n name: \"canDownload\",\n type: \"boolean\",\n title: \"Downloadable\",\n initialValue: true,\n description: \"The file will be downloaded when the link is clicked.\",\n options: { layout: \"switch\" },\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: \"openInNewTab\",\n type: \"boolean\",\n title: \"Open in new tab\",\n description: \"Open the link in a new tab.\",\n initialValue: false,\n options: { layout: \"switch\" },\n ...visibleIfKind([LinkKind.external, LinkKind.internal]),\n }),\n ],\n preview: {\n select: {\n kind: \"kind\",\n email: \"email\",\n phone: \"phone\",\n customText: \"customText\",\n fileName: \"file.asset.originalFilename\",\n externalUrl: \"external\",\n internalUri: \"internal.uri.current\",\n internalTitle: \"internal.title\",\n },\n prepare: (props) => {\n return buildLinkPreview(props);\n },\n },\n }),\n ],\n },\n };\n});\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n buildLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/input.tsx","../src/preview.tsx","../src/types.tsx","../src/index.tsx"],"sourcesContent":["import { useFieldMember } from \"@madebywild/sanity-utils\";\nimport { AsyncAutocomplete } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport { Box, Card, Stack, Text } from \"@sanity/ui\";\nimport * as changeCase from \"change-case\";\nimport * as React from \"react\";\nimport type { ObjectInputProps, ObjectMember, Reference } from \"sanity\";\nimport { MemberField, set, unset, useClient } from \"sanity\";\nimport type { FieldOptions } from \"./types\";\n\nfunction FieldInput(props: ObjectInputProps) {\n const options = props.schemaType.options as FieldOptions | undefined;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n if (options?.noCustomText && member.name === \"customText\") return null;\n return <MemberField key={member.key} member={member} {...props} />;\n })}\n </Stack>\n );\n}\n\nconst SectionsQuery = `\n *[_id == $pageId && defined(pageBuilder.sectionsArray)][0]{\n \"sections\": array::compact(pageBuilder.sectionsArray[]{\n \"value\": _key,\n \"label\": coalesce(sectionSettings.sectionTitle, _type),\n }),\n }.sections\n`;\n\nfunction InternalLinkInput(props: ObjectInputProps) {\n const linkFieldMember = useFieldMember(props.members, \"link\");\n\n const selectedLink = props.value?.link as Reference | undefined;\n const selectedSection = props.value?.sectionTarget as string | undefined;\n\n // Reset sectionTarget if link is removed.\n React.useEffect(() => {\n if (!selectedLink?._ref && selectedSection !== undefined) {\n props.onChange(unset([\"sectionTarget\"]));\n }\n }, [selectedLink, selectedSection, props.onChange]);\n\n const client = useClient({ apiVersion: \"2025-10-21\" });\n\n const fetchSections = React.useCallback(async () => {\n if (!selectedLink?._ref) return [];\n\n try {\n const items = await client.fetch(SectionsQuery, { pageId: selectedLink._ref });\n return items;\n } catch {\n return [];\n }\n }, [client, selectedLink?._ref]);\n\n return (\n <Stack space={2}>\n {linkFieldMember && <MemberField member={linkFieldMember} {...props} />}\n {selectedLink?._ref && (\n <AsyncAutocomplete\n placeholder=\"Select section\"\n noOptionsPlaceholder=\"No sections found\"\n listItems={fetchSections}\n value={selectedSection}\n renderValue={(value, opt) => {\n return opt?.label ? changeCase.capitalCase(opt.label) : value;\n }}\n onChange={(value) => {\n const next = value ? set(value, [\"sectionTarget\"]) : unset([\"sectionTarget\"]);\n return props.onChange(next);\n }}\n renderOption={({ label, value }) => {\n return (\n <Card as=\"button\">\n <Box flex={1} padding={3}>\n <Text size={2}>{changeCase.capitalCase(label ?? value)}</Text>\n </Box>\n </Card>\n );\n }}\n />\n )}\n </Stack>\n );\n}\n\nexport { FieldInput, InternalLinkInput };\n","import type { LinkKind } from \"./types\";\n\n/** @public */\nexport function buildLinkPreview({\n kind,\n email,\n phone,\n fileName,\n customText,\n internalUri,\n externalUrl,\n internalTitle,\n}: {\n kind?: string;\n email?: string;\n phone?: string;\n fileName?: string;\n customText?: string;\n externalUrl?: string;\n internalUri?: string;\n internalTitle?: string;\n}) {\n switch (kind as keyof typeof LinkKind) {\n case \"internal\": {\n return {\n title: customText ?? internalTitle ?? \"Internal Link\",\n subtitle: internalUri,\n media: () => <>📄</>,\n };\n }\n case \"external\":\n return {\n title: customText ?? \"External Link\",\n subtitle: externalUrl,\n media: () => <>🌍</>,\n };\n case \"email\":\n return {\n title: customText ?? \"Email Link\",\n subtitle: email,\n media: () => <>📧</>,\n };\n case \"phone\":\n return {\n title: customText ?? \"Phone Link\",\n subtitle: phone,\n media: () => <>☎️</>,\n };\n case \"file\":\n return {\n title: customText ?? \"File Link\",\n subtitle: fileName,\n media: () => <>📃</>,\n };\n default:\n return {\n title: customText ?? \"Empty Link\",\n media: () => <>⛓️‍💥</>,\n };\n }\n}\n","import type { ListItem } from \"@madebywild/sanity-utils/async-autocomplete\";\nimport type { ObjectDefinition, ObjectOptions, ReferenceTo } from \"sanity\";\n\n/** @public */\nexport const typeName = \"wild.link\" as const;\n\n/** @public */\nexport const LinkKind = {\n internal: \"internal\",\n external: \"external\",\n email: \"email\",\n phone: \"phone\",\n file: \"file\",\n} as const;\n\n/** @public */\nexport type SectionQueryResult = ListItem[];\n\n/** @public */\nexport type PluginConfig = {\n weakReferences?: boolean;\n internalLinkSchemaTypes: ReferenceTo;\n};\n\n/** @public */\nexport type FieldOptions = ObjectOptions & {\n noCustomText?: boolean;\n};\n\n// Add the custom field definition to Sanity's intrinsic definitions\n// so that type checking works correctly when using this field type.\ndeclare module \"sanity\" {\n export interface IntrinsicDefinitions {\n [typeName]: Omit<ObjectDefinition, \"type\" | \"fields\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n","import { requiredIf, visibleIf } from \"@madebywild/sanity-utils\";\nimport { defineField, definePlugin, defineType } from \"sanity\";\nimport { FieldInput, InternalLinkInput } from \"./input\";\nimport { buildLinkPreview } from \"./preview\";\nimport { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, typeName } from \"./types\";\n\nconst visibleIfKind = visibleIf(\"kind\");\nconst requiredIfKind = requiredIf(\"kind\");\n\n/** @public */\nconst wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {\n return {\n name: \"@madebywild/sanity-link-field\",\n schema: {\n types: [\n defineType({\n name: typeName,\n type: \"object\",\n title: \"Link\",\n description: \"Link to an internal page, external URL and more.\",\n icon: () => <>🔗</>,\n components: {\n input: (props) => <FieldInput {...props} />,\n },\n fields: [\n defineField({\n name: \"kind\",\n type: \"string\",\n title: \"Link Kind\",\n description: \"Select the kind of link.\",\n validation: (R) => R.required().error(\"Select a link kind.\"),\n options: {\n layout: \"radio\",\n direction: \"horizontal\",\n list: [\n { title: \"📄 Internal\", value: LinkKind.internal },\n { title: \"🌍 External\", value: LinkKind.external },\n { title: \"📧 Email\", value: LinkKind.email },\n { title: \"☎️ Phone\", value: LinkKind.phone },\n { title: \"📃 File\", value: LinkKind.file },\n ],\n },\n }),\n defineField({\n name: LinkKind.external,\n type: \"url\",\n title: \"External Link\",\n ...visibleIfKind(LinkKind.external),\n ...requiredIfKind(LinkKind.external),\n }),\n defineField({\n name: LinkKind.email,\n type: \"string\",\n title: \"Email\",\n ...visibleIfKind(LinkKind.email),\n ...requiredIfKind(LinkKind.email),\n }),\n defineField({\n name: LinkKind.phone,\n type: \"string\",\n title: \"Phone\",\n ...visibleIfKind(LinkKind.phone),\n ...requiredIfKind(LinkKind.phone),\n }),\n defineField({\n name: LinkKind.file,\n type: \"file\",\n title: \"File\",\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: LinkKind.internal,\n type: \"object\",\n ...visibleIfKind(LinkKind.internal),\n ...requiredIfKind(LinkKind.internal),\n options: { collapsed: false, collapsible: false },\n components: {\n field: (props) => <>{props.children}</>,\n input: (props) => <InternalLinkInput {...props} />,\n },\n fields: [\n defineField({\n type: \"reference\",\n name: \"link\",\n title: \"Internal Link\",\n description: \"Select a page and an optional section target.\",\n weak: config.weakReferences ?? true,\n to: config.internalLinkSchemaTypes,\n options: {\n disableNew: true,\n },\n }),\n defineField({\n type: \"string\",\n name: \"sectionTarget\",\n title: \"Section Target\",\n }),\n ],\n }),\n defineField({\n name: \"customText\",\n type: \"string\",\n title: \"Custom text\",\n description: \"Will take precedence over inferred text.\",\n }),\n defineField({\n name: \"canDownload\",\n type: \"boolean\",\n title: \"Downloadable\",\n initialValue: true,\n description: \"The file will be downloaded when the link is clicked.\",\n options: { layout: \"switch\" },\n ...visibleIfKind(LinkKind.file),\n ...requiredIfKind(LinkKind.file),\n }),\n defineField({\n name: \"openInNewTab\",\n type: \"boolean\",\n title: \"Open in new tab\",\n description: \"Open the link in a new tab.\",\n initialValue: false,\n options: { layout: \"switch\" },\n ...visibleIfKind([LinkKind.external, LinkKind.internal]),\n }),\n ],\n preview: {\n select: {\n kind: \"kind\",\n email: \"email\",\n phone: \"phone\",\n customText: \"customText\",\n fileName: \"file.asset.originalFilename\",\n externalUrl: \"external\",\n internalUri: \"internal.uri.current\",\n internalTitle: \"internal.title\",\n },\n prepare: (props) => {\n return buildLinkPreview(props);\n },\n },\n }),\n ],\n },\n };\n});\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n buildLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["FieldInput","props","$","_c","options","schemaType","t0","noCustomText","members","map","member","kind","name","key","t1","SectionsQuery","InternalLinkInput","linkFieldMember","useFieldMember","selectedLink","value","link","selectedSection","sectionTarget","React","useEffect","_ref","undefined","onChange","unset","client","useClient","apiVersion","fetchSections","useCallback","fetch","pageId","opt","label","changeCase","capitalCase","next","set","buildLinkPreview","email","phone","fileName","customText","internalUri","externalUrl","internalTitle","title","subtitle","media","typeName","LinkKind","internal","external","file","visibleIfKind","visibleIf","requiredIfKind","requiredIf","wildSanityLinkFieldPlugin","definePlugin","config","schema","types","defineType","type","description","icon","components","input","fields","defineField","validation","R","required","error","layout","direction","list","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madebywild/sanity-link-field",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "UNLICENSED",
@@ -22,22 +22,23 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "change-case": "^5.4.4",
25
- "@madebywild/sanity-utils": "0.2.2"
25
+ "@madebywild/sanity-utils": "0.2.4"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@sanity/ui": "^3.1",
29
- "sanity": "^4.17",
30
29
  "react": "^19",
31
- "react-dom": "^19"
30
+ "react-dom": "^19",
31
+ "sanity": "^4.17"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@sanity/pkg-utils": "^9.2",
35
- "sanity": "^4.17",
35
+ "@types/react": "^19",
36
+ "@types/react-dom": "^19",
37
+ "babel-plugin-react-compiler": "1.0.0",
36
38
  "react": "^19",
37
39
  "react-dom": "^19",
38
- "typescript": "^5",
39
- "@types/react": "^19",
40
- "@types/react-dom": "^19"
40
+ "sanity": "^4.17",
41
+ "typescript": "^5"
41
42
  },
42
43
  "scripts": {
43
44
  "build": "pkg-utils build --strict",
package/src/input.tsx CHANGED
@@ -45,36 +45,44 @@ function InternalLinkInput(props: ObjectInputProps) {
45
45
 
46
46
  const client = useClient({ apiVersion: "2025-10-21" });
47
47
 
48
- const fetchSections = React.useCallback(() => {
48
+ const fetchSections = React.useCallback(async () => {
49
49
  if (!selectedLink?._ref) return [];
50
- return client.fetch(SectionsQuery, { pageId: selectedLink._ref }).catch(() => []);
51
- }, [client, selectedLink, SectionsQuery]);
50
+
51
+ try {
52
+ const items = await client.fetch(SectionsQuery, { pageId: selectedLink._ref });
53
+ return items;
54
+ } catch {
55
+ return [];
56
+ }
57
+ }, [client, selectedLink?._ref]);
52
58
 
53
59
  return (
54
60
  <Stack space={2}>
55
61
  {linkFieldMember && <MemberField member={linkFieldMember} {...props} />}
56
- <AsyncAutocomplete
57
- placeholder="Select section"
58
- noOptionsPlaceholder="No sections found"
59
- listItems={fetchSections}
60
- value={selectedSection}
61
- renderValue={(value, opt) => {
62
- return opt?.label ? changeCase.capitalCase(opt.label) : value;
63
- }}
64
- onChange={(value) => {
65
- const next = value ? set(value, ["sectionTarget"]) : unset(["sectionTarget"]);
66
- return props.onChange(next);
67
- }}
68
- renderOption={({ label, value }) => {
69
- return (
70
- <Card as="button">
71
- <Box flex={1} padding={3}>
72
- <Text size={2}>{changeCase.capitalCase(label ?? value)}</Text>
73
- </Box>
74
- </Card>
75
- );
76
- }}
77
- />
62
+ {selectedLink?._ref && (
63
+ <AsyncAutocomplete
64
+ placeholder="Select section"
65
+ noOptionsPlaceholder="No sections found"
66
+ listItems={fetchSections}
67
+ value={selectedSection}
68
+ renderValue={(value, opt) => {
69
+ return opt?.label ? changeCase.capitalCase(opt.label) : value;
70
+ }}
71
+ onChange={(value) => {
72
+ const next = value ? set(value, ["sectionTarget"]) : unset(["sectionTarget"]);
73
+ return props.onChange(next);
74
+ }}
75
+ renderOption={({ label, value }) => {
76
+ return (
77
+ <Card as="button">
78
+ <Box flex={1} padding={3}>
79
+ <Text size={2}>{changeCase.capitalCase(label ?? value)}</Text>
80
+ </Box>
81
+ </Card>
82
+ );
83
+ }}
84
+ />
85
+ )}
78
86
  </Stack>
79
87
  );
80
88
  }
package/src/types.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ListItem } from "@madebywild/sanity-utils/async-autocomplete";
2
- import type { ObjectOptions, ReferenceTo, StringDefinition } from "sanity";
2
+ import type { ObjectDefinition, ObjectOptions, ReferenceTo } from "sanity";
3
3
 
4
4
  /** @public */
5
5
  export const typeName = "wild.link" as const;
@@ -31,8 +31,9 @@ export type FieldOptions = ObjectOptions & {
31
31
  // so that type checking works correctly when using this field type.
32
32
  declare module "sanity" {
33
33
  export interface IntrinsicDefinitions {
34
- [typeName]: Omit<StringDefinition, "type" | "fields"> & {
34
+ [typeName]: Omit<ObjectDefinition, "type" | "fields" | "options"> & {
35
35
  type: typeof typeName;
36
+ options?: FieldOptions;
36
37
  };
37
38
  }
38
39
  }