@madebywild/sanity-link-field 0.3.5 → 0.3.7

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
@@ -131,11 +131,8 @@ const typeName = "wild.link", LinkKind = {
131
131
  type: "string",
132
132
  title: "Link Kind",
133
133
  description: "Select the kind of link.",
134
- // TODO: Figure out a good way to enable the consumer to make this required.
135
- // validation: (R) => R.required().error("Select a link kind."),
136
134
  options: {
137
- layout: "radio",
138
- direction: "horizontal",
135
+ layout: "dropdown",
139
136
  list: [{
140
137
  title: "\u{1F4C4} Internal",
141
138
  value: LinkKind.internal
@@ -247,8 +244,12 @@ const typeName = "wild.link", LinkKind = {
247
244
  })]
248
245
  }
249
246
  }));
247
+ function requireLink(R) {
248
+ return R.custom((ctx) => ctx?.kind ? !0 : "Select the kind of link.");
249
+ }
250
250
  exports.LinkKind = LinkKind;
251
251
  exports.buildLinkPreview = buildLinkPreview;
252
+ exports.requireLink = requireLink;
252
253
  exports.typeName = typeName;
253
254
  exports.wildSanityLinkFieldPlugin = wildSanityLinkFieldPlugin;
254
255
  //# sourceMappingURL=index.cjs.map
@@ -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(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 // TODO: Figure out a good way to enable the consumer to make this required.\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 }),\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","layout","direction","list","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare"],"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 type { ObjectRule } from \"sanity\";\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 options: {\n layout: \"dropdown\",\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 }),\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\nfunction requireLink(R: ObjectRule) {\n return R.custom((ctx) => (!ctx?.kind ? \"Select the kind of link.\" : true));\n}\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n requireLink,\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","layout","list","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare","requireLink","R","custom","ctx"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as sanity0 from "sanity";
2
- import { ObjectDefinition, ObjectOptions, ReferenceTo } from "sanity";
2
+ import { ObjectDefinition, ObjectOptions, ObjectRule, ReferenceTo } from "sanity";
3
3
  import * as react1 from "react";
4
4
  /** @public */
5
5
  declare function buildLinkPreview({
@@ -66,4 +66,5 @@ declare module "sanity" {
66
66
  }
67
67
  /** @public */
68
68
  declare const wildSanityLinkFieldPlugin: sanity0.Plugin<PluginConfig>;
69
- export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, buildLinkPreview, typeName, wildSanityLinkFieldPlugin };
69
+ declare function requireLink(R: ObjectRule): ObjectRule;
70
+ export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, buildLinkPreview, requireLink, typeName, wildSanityLinkFieldPlugin };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as sanity0 from "sanity";
2
- import { ObjectDefinition, ObjectOptions, ReferenceTo } from "sanity";
2
+ import { ObjectDefinition, ObjectOptions, ObjectRule, ReferenceTo } from "sanity";
3
3
  import * as react1 from "react";
4
4
  /** @public */
5
5
  declare function buildLinkPreview({
@@ -66,4 +66,5 @@ declare module "sanity" {
66
66
  }
67
67
  /** @public */
68
68
  declare const wildSanityLinkFieldPlugin: sanity0.Plugin<PluginConfig>;
69
- export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, buildLinkPreview, typeName, wildSanityLinkFieldPlugin };
69
+ declare function requireLink(R: ObjectRule): ObjectRule;
70
+ export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, buildLinkPreview, requireLink, typeName, wildSanityLinkFieldPlugin };
package/dist/index.js CHANGED
@@ -120,11 +120,8 @@ const typeName = "wild.link", LinkKind = {
120
120
  type: "string",
121
121
  title: "Link Kind",
122
122
  description: "Select the kind of link.",
123
- // TODO: Figure out a good way to enable the consumer to make this required.
124
- // validation: (R) => R.required().error("Select a link kind."),
125
123
  options: {
126
- layout: "radio",
127
- direction: "horizontal",
124
+ layout: "dropdown",
128
125
  list: [{
129
126
  title: "\u{1F4C4} Internal",
130
127
  value: LinkKind.internal
@@ -236,9 +233,13 @@ const typeName = "wild.link", LinkKind = {
236
233
  })]
237
234
  }
238
235
  }));
236
+ function requireLink(R) {
237
+ return R.custom((ctx) => ctx?.kind ? !0 : "Select the kind of link.");
238
+ }
239
239
  export {
240
240
  LinkKind,
241
241
  buildLinkPreview,
242
+ requireLink,
242
243
  typeName,
243
244
  wildSanityLinkFieldPlugin
244
245
  };
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(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 // TODO: Figure out a good way to enable the consumer to make this required.\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 }),\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","layout","direction","list","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare"],"mappings":";;;;;;;;AASA,SAAAA,WAAAC,OAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GACEC,UAAgBH,MAAKI,WAAWD;AAAqC,MAAAE;AAAAJ,WAAAE,SAAAG,gBAAAL,SAAAD,SAIhEK,KAAAL,MAAKO,QAAQC,IAAKC,YACbA,OAAMC,SAAU,WAChBP,SAAOG,gBAAkBG,OAAME,SAAU,eAAqB,2BAC1D,aAAA,EAAqCF,QAAM,GAAMT,MAAAA,GAAhCS,OAAMG,GAA+B,CAC/D,GAACX,EAAA,CAAA,IAAAE,SAAAG,cAAAL,OAAAD,OAAAC,OAAAI,MAAAA,KAAAJ,EAAA,CAAA;AAAA,MAAAY;AAAA,SAAAZ,SAAAI,MALJQ,KAAA,oBAAC,OAAA,EAAa,OAAA,GACXR,UAAAA,GAAAA,CAKH,GAAQJ,OAAAI,IAAAJ,OAAAY,MAAAA,KAAAZ,EAAA,CAAA,GANRY;AAMQ;AAIZ,MAAMC,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAStB,SAASC,kBAAkBf,OAAyB;AAClD,QAAMgB,kBAAkBC,eAAejB,MAAMO,SAAS,MAAM,GAEtDW,eAAelB,MAAMmB,OAAOC,MAC5BC,kBAAkBrB,MAAMmB,OAAOG;AAGrCC,QAAMC,UAAU,MAAM;AAChB,KAACN,cAAcO,QAAQJ,oBAAoBK,UAC7C1B,MAAM2B,SAASC,MAAM,CAAC,eAAe,CAAC,CAAC;AAAA,EAE3C,GAAG,CAACV,cAAcG,iBAAiBrB,MAAM2B,QAAQ,CAAC;AAElD,QAAME,SAASC,UAAU;AAAA,IAAEC,YAAY;AAAA,EAAA,CAAc,GAE/CC,gBAAgBT,MAAMU,YAAY,YAAY;AAClD,QAAI,CAACf,cAAcO,KAAM,QAAO,CAAA;AAEhC,QAAI;AAEF,aADc,MAAMI,OAAOK,MAAMpB,eAAe;AAAA,QAAEqB,QAAQjB,aAAaO;AAAAA,MAAAA,CAAM;AAAA,IAE/E,QAAQ;AACN,aAAO,CAAA;AAAA,IACT;AAAA,EACF,GAAG,CAACI,QAAQX,cAAcO,IAAI,CAAC;AAE/B,SACE,qBAAC,OAAA,EAAM,OAAO,GACXT,UAAAA;AAAAA,IAAAA,mBAAmB,oBAAC,aAAA,EAAY,QAAQA,iBAAiB,GAAIhB,OAAM;AAAA,IACnEkB,cAAcO,QACb,oBAAC,mBAAA,EACC,aAAY,kBACZ,sBAAqB,qBACrB,WAAWO,eACX,OAAOX,iBACP,aAAa,CAACF,OAAOiB,QACZA,KAAKC,QAAQC,WAAWC,YAAYH,IAAIC,KAAK,IAAIlB,OAE1D,UAAWA,CAAAA,YAAU;AACnB,YAAMqB,OAAOrB,UAAQsB,IAAItB,SAAO,CAAC,eAAe,CAAC,IAAIS,MAAM,CAAC,eAAe,CAAC;AAC5E,aAAO5B,MAAM2B,SAASa,IAAI;AAAA,IAC5B,GACA,cAAc,CAAC;AAAA,MAAEH;AAAAA,MAAOlB,OAAAA;AAAAA,IAAAA,0BAEnB,MAAA,EAAK,IAAG,UACP,UAAA,oBAAC,KAAA,EAAI,MAAM,GAAG,SAAS,GACrB,8BAAC,MAAA,EAAK,MAAM,GAAImB,UAAAA,WAAWC,YAAYF,SAASlB,OAAK,EAAA,CAAE,EAAA,CACzD,EAAA,CACF,EAAA,CAEF;AAAA,EAAA,GAGR;AAEJ;ACpFO,SAASuB,iBAAiB;AAAA,EAC/BhC;AAAAA,EACAiC;AAAAA,EACAC;AAAAA,EACAC;AAAAA,EACAC;AAAAA,EACAC;AAAAA,EACAC;AAAAA,EACAC;AAUF,GAAG;AACD,UAAQvC,MAAAA;AAAAA,IACN,KAAK;AACH,aAAO;AAAA,QACLwC,OAAOJ,cAAcG,iBAAiB;AAAA,QACtCE,UAAUJ;AAAAA,QACVK,OAAOA,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,MAAA;AAAA,IAGrB,KAAK;AACH,aAAO;AAAA,QACLF,OAAOJ,cAAc;AAAA,QACrBK,UAAUH;AAAAA,QACVI,OAAOA,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,MAAA;AAAA,IAErB,KAAK;AACH,aAAO;AAAA,QACLF,OAAOJ,cAAc;AAAA,QACrBK,UAAUR;AAAAA,QACVS,OAAOA,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,MAAA;AAAA,IAErB,KAAK;AACH,aAAO;AAAA,QACLF,OAAOJ,cAAc;AAAA,QACrBK,UAAUP;AAAAA,QACVQ,OAAOA,MAAM,oBAAA,UAAA,EAAE,UAAA,eAAA,CAAE;AAAA,MAAA;AAAA,IAErB,KAAK;AACH,aAAO;AAAA,QACLF,OAAOJ,cAAc;AAAA,QACrBK,UAAUN;AAAAA,QACVO,OAAOA,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,MAAA;AAAA,IAErB;AACE,aAAO;AAAA,QACLF,OAAOJ,cAAc;AAAA,QACrBM,OAAOA,MAAM,oBAAA,UAAA,EAAE,UAAA,8BAAA,CAAK;AAAA,MAAA;AAAA,EACtB;AAEN;ACxDO,MAAMC,WAAW,aAGXC,WAAW;AAAA,EACtBC,UAAU;AAAA,EACVC,UAAU;AAAA,EACVb,OAAO;AAAA,EACPC,OAAO;AAAA,EACPa,MAAM;AACR,GCPMC,gBAAgBC,UAAU,MAAM,GAChCC,iBAAiBC,WAAW,MAAM,GAGlCC,4BAA4BC,aAA4BC,CAAAA,YACrD;AAAA,EACLrD,MAAM;AAAA,EACNsD,QAAQ;AAAA,IACNC,OAAO,CACLC,WAAW;AAAA,MACTxD,MAAM0C;AAAAA,MACNe,MAAM;AAAA,MACNlB,OAAO;AAAA,MACPmB,aAAa;AAAA,MACbC,MAAMA,MAAM,oBAAA,UAAA,EAAE,UAAA,YAAA,CAAE;AAAA,MAChBC,YAAY;AAAA,QACVC,OAAQxE,CAAAA,UAAU,oBAAC,YAAA,EAAW,GAAIA,MAAAA,CAAM;AAAA,MAAA;AAAA,MAE1CyE,QAAQ,CACNC,YAAY;AAAA,QACV/D,MAAM;AAAA,QACNyD,MAAM;AAAA,QACNlB,OAAO;AAAA,QACPmB,aAAa;AAAA;AAAA;AAAA,QAGblE,SAAS;AAAA,UACPwE,QAAQ;AAAA,UACRC,WAAW;AAAA,UACXC,MAAM,CACJ;AAAA,YAAE3B,OAAO;AAAA,YAAe/B,OAAOmC,SAASC;AAAAA,UAAAA,GACxC;AAAA,YAAEL,OAAO;AAAA,YAAe/B,OAAOmC,SAASE;AAAAA,UAAAA,GACxC;AAAA,YAAEN,OAAO;AAAA,YAAY/B,OAAOmC,SAASX;AAAAA,UAAAA,GACrC;AAAA,YAAEO,OAAO;AAAA,YAAY/B,OAAOmC,SAASV;AAAAA,UAAAA,GACrC;AAAA,YAAEM,OAAO;AAAA,YAAW/B,OAAOmC,SAASG;AAAAA,UAAAA,CAAM;AAAA,QAAA;AAAA,MAE9C,CACD,GACDiB,YAAY;AAAA,QACV/D,MAAM2C,SAASE;AAAAA,QACfY,MAAM;AAAA,QACNlB,OAAO;AAAA,QACP,GAAGQ,cAAcJ,SAASE,QAAQ;AAAA,QAClC,GAAGI,eAAeN,SAASE,QAAQ;AAAA,MAAA,CACpC,GACDkB,YAAY;AAAA,QACV/D,MAAM2C,SAASX;AAAAA,QACfyB,MAAM;AAAA,QACNlB,OAAO;AAAA,QACP,GAAGQ,cAAcJ,SAASX,KAAK;AAAA,QAC/B,GAAGiB,eAAeN,SAASX,KAAK;AAAA,MAAA,CACjC,GACD+B,YAAY;AAAA,QACV/D,MAAM2C,SAASV;AAAAA,QACfwB,MAAM;AAAA,QACNlB,OAAO;AAAA,QACP,GAAGQ,cAAcJ,SAASV,KAAK;AAAA,QAC/B,GAAGgB,eAAeN,SAASV,KAAK;AAAA,MAAA,CACjC,GACD8B,YAAY;AAAA,QACV/D,MAAM2C,SAASG;AAAAA,QACfW,MAAM;AAAA,QACNlB,OAAO;AAAA,QACP,GAAGQ,cAAcJ,SAASG,IAAI;AAAA,QAC9B,GAAGG,eAAeN,SAASG,IAAI;AAAA,MAAA,CAChC,GACDiB,YAAY;AAAA,QACV/D,MAAM2C,SAASC;AAAAA,QACfa,MAAM;AAAA,QACN,GAAGV,cAAcJ,SAASC,QAAQ;AAAA,QAClC,GAAGK,eAAeN,SAASC,QAAQ;AAAA,QACnCpD,SAAS;AAAA,UAAE2E,WAAW;AAAA,UAAOC,aAAa;AAAA,QAAA;AAAA,QAC1CR,YAAY;AAAA,UACVS,OAAQhF,CAAAA,UAAU,oBAAA,UAAA,EAAGA,UAAAA,MAAMiF,UAAS;AAAA,UACpCT,OAAQxE,CAAAA,UAAU,oBAAC,mBAAA,EAAkB,GAAIA,MAAAA,CAAM;AAAA,QAAA;AAAA,QAEjDyE,QAAQ,CACNC,YAAY;AAAA,UACVN,MAAM;AAAA,UACNzD,MAAM;AAAA,UACNuC,OAAO;AAAA,UACPmB,aAAa;AAAA,UACba,MAAMlB,OAAOmB,kBAAkB;AAAA,UAC/BC,IAAIpB,OAAOqB;AAAAA,UACXlF,SAAS;AAAA,YACPmF,YAAY;AAAA,UAAA;AAAA,QACd,CACD,GACDZ,YAAY;AAAA,UACVN,MAAM;AAAA,UACNzD,MAAM;AAAA,UACNuC,OAAO;AAAA,QAAA,CACR,CAAC;AAAA,MAAA,CAEL,GACDwB,YAAY;AAAA,QACV/D,MAAM;AAAA,QACNyD,MAAM;AAAA,QACNlB,OAAO;AAAA,QACPmB,aAAa;AAAA,MAAA,CACd,GACDK,YAAY;AAAA,QACV/D,MAAM;AAAA,QACNyD,MAAM;AAAA,QACNlB,OAAO;AAAA,QACPqC,cAAc;AAAA,QACdlB,aAAa;AAAA,QACblE,SAAS;AAAA,UAAEwE,QAAQ;AAAA,QAAA;AAAA,QACnB,GAAGjB,cAAcJ,SAASG,IAAI;AAAA,MAAA,CAC/B,GACDiB,YAAY;AAAA,QACV/D,MAAM;AAAA,QACNyD,MAAM;AAAA,QACNlB,OAAO;AAAA,QACPmB,aAAa;AAAA,QACbkB,cAAc;AAAA,QACdpF,SAAS;AAAA,UAAEwE,QAAQ;AAAA,QAAA;AAAA,QACnB,GAAGjB,cAAc,CAACJ,SAASE,UAAUF,SAASC,QAAQ,CAAC;AAAA,MAAA,CACxD,CAAC;AAAA,MAEJiC,SAAS;AAAA,QACPC,QAAQ;AAAA,UACN/E,MAAM;AAAA,UACNiC,OAAO;AAAA,UACPC,OAAO;AAAA,UACPE,YAAY;AAAA,UACZD,UAAU;AAAA,UACVG,aAAa;AAAA,UACbD,aAAa;AAAA,UACbE,eAAe;AAAA,QAAA;AAAA,QAEjByC,SAAU1F,CAAAA,UACD0C,iBAAiB1C,KAAK;AAAA,MAAA;AAAA,IAEjC,CACD,CAAC;AAAA,EAAA;AAGR,EACD;"}
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 type { ObjectRule } from \"sanity\";\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 options: {\n layout: \"dropdown\",\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 }),\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\nfunction requireLink(R: ObjectRule) {\n return R.custom((ctx) => (!ctx?.kind ? \"Select the kind of link.\" : true));\n}\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n requireLink,\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","layout","list","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare","requireLink","R","custom","ctx"],"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.3.5",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "UNLICENSED",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "change-case": "^5.4.4",
25
- "@madebywild/sanity-utils": "0.3.5"
25
+ "@madebywild/sanity-utils": "0.3.6"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@sanity/ui": "^3.1",
package/src/index.tsx CHANGED
@@ -1,4 +1,5 @@
1
1
  import { requiredIf, visibleIf } from "@madebywild/sanity-utils";
2
+ import type { ObjectRule } from "sanity";
2
3
  import { defineField, definePlugin, defineType } from "sanity";
3
4
  import { FieldInput, InternalLinkInput } from "./input";
4
5
  import { buildLinkPreview } from "./preview";
@@ -28,11 +29,8 @@ const wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {
28
29
  type: "string",
29
30
  title: "Link Kind",
30
31
  description: "Select the kind of link.",
31
- // TODO: Figure out a good way to enable the consumer to make this required.
32
- // validation: (R) => R.required().error("Select a link kind."),
33
32
  options: {
34
- layout: "radio",
35
- direction: "horizontal",
33
+ layout: "dropdown",
36
34
  list: [
37
35
  { title: "📄 Internal", value: LinkKind.internal },
38
36
  { title: "🌍 External", value: LinkKind.external },
@@ -145,10 +143,15 @@ const wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {
145
143
  };
146
144
  });
147
145
 
146
+ function requireLink(R: ObjectRule) {
147
+ return R.custom((ctx) => (!ctx?.kind ? "Select the kind of link." : true));
148
+ }
149
+
148
150
  export {
149
151
  wildSanityLinkFieldPlugin,
150
152
  typeName,
151
153
  LinkKind,
154
+ requireLink,
152
155
  buildLinkPreview,
153
156
  type PluginConfig,
154
157
  type FieldOptions,