@madebywild/sanity-link-field 0.3.13 → 0.3.14

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
@@ -191,7 +191,9 @@ const typeName = "wild.link", LinkKind = {
191
191
  name: LinkKind.internal,
192
192
  type: "object",
193
193
  ...visibleIfKind(LinkKind.internal),
194
- ...requiredIfKind(LinkKind.internal),
194
+ ...requiredIfKind(LinkKind.internal, {
195
+ path: ["link"]
196
+ }),
195
197
  options: {
196
198
  collapsed: !1,
197
199
  collapsible: !1
@@ -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 const extensions = options?.extensions;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n\n // Only show enabled extensions.\n if (!extensions?.includes(\"customText\") && member.name === \"customText\") return null;\n\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 selectLinkPreview(namespace?: string) {\n const ns = namespace ? (`${namespace}.` as const) : \"\";\n\n const kind = \"kind\";\n const email = \"email\";\n const phone = \"phone\";\n const fileName = \"file.asset.originalFilename\";\n const customText = \"customText\";\n const externalUrl = \"external\";\n const internalTitle = \"internal.title\";\n const internalUri = \"internal.uri.current\";\n\n return {\n kind: `${ns}${kind}`,\n email: `${ns}${email}`,\n phone: `${ns}${phone}`,\n fileName: `${ns}${fileName}`,\n customText: `${ns}${customText}`,\n internalUri: `${ns}${internalUri}`,\n externalUrl: `${ns}${externalUrl}`,\n internalTitle: `${ns}${internalTitle}`,\n } as const;\n}\n\n/** @public */\nexport function prepareLinkPreview({\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 const LinkExtension = {\n customText: \"customText\",\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 extensions?: (keyof typeof LinkExtension)[];\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 { prepareLinkPreview, selectLinkPreview } 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: selectLinkPreview(),\n prepare: (props) => prepareLinkPreview(props),\n },\n }),\n ],\n },\n };\n});\n\nfunction requireLink(R: ObjectRule) {\n return R.custom((ctx) => (!ctx?.kind ? { message: \"Select the kind of link.\", path: [\"kind\"] } : true));\n}\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n requireLink,\n selectLinkPreview,\n prepareLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["FieldInput","props","$","_c","extensions","schemaType","options","t0","members","map","member","kind","includes","name","jsx","MemberField","key","t1","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","selectLinkPreview","namespace","ns","email","phone","fileName","customText","internalUri","externalUrl","internalTitle","prepareLinkPreview","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","message","path"],"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 const extensions = options?.extensions;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n\n // Only show enabled extensions.\n if (!extensions?.includes(\"customText\") && member.name === \"customText\") return null;\n\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\ntype PreviewCtx = {\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\n/** @public */\nexport function selectLinkPreview(namespace?: string) {\n const ns = namespace ? (`${namespace}.` as const) : \"\";\n\n const kind = \"kind\";\n const email = \"email\";\n const phone = \"phone\";\n const fileName = \"file.asset.originalFilename\";\n const customText = \"customText\";\n const externalUrl = \"external\";\n const internalTitle = \"internal.title\";\n const internalUri = \"internal.uri.current\";\n\n return {\n kind: `${ns}${kind}`,\n email: `${ns}${email}`,\n phone: `${ns}${phone}`,\n fileName: `${ns}${fileName}`,\n customText: `${ns}${customText}`,\n internalUri: `${ns}${internalUri}`,\n externalUrl: `${ns}${externalUrl}`,\n internalTitle: `${ns}${internalTitle}`,\n } as const satisfies PreviewCtx;\n}\n\n/** @public */\nexport function prepareLinkPreview({\n kind,\n email,\n phone,\n fileName,\n customText,\n internalUri,\n externalUrl,\n internalTitle,\n}: PreviewCtx) {\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 const LinkExtension = {\n customText: \"customText\",\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 extensions?: (keyof typeof LinkExtension)[];\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 { prepareLinkPreview, selectLinkPreview } 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, { path: [\"link\"] }),\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: selectLinkPreview(),\n prepare: (props) => prepareLinkPreview(props),\n },\n }),\n ],\n },\n };\n});\n\nfunction requireLink(R: ObjectRule) {\n return R.custom((ctx) => (!ctx?.kind ? { message: \"Select the kind of link.\", path: [\"kind\"] } : true));\n}\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n requireLink,\n selectLinkPreview,\n prepareLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["FieldInput","props","$","_c","extensions","schemaType","options","t0","members","map","member","kind","includes","name","jsx","MemberField","key","t1","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","selectLinkPreview","namespace","ns","email","phone","fileName","customText","internalUri","externalUrl","internalTitle","prepareLinkPreview","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","path","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare","requireLink","R","custom","ctx","message"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,16 @@
1
1
  import * as sanity0 from "sanity";
2
2
  import { ObjectDefinition, ObjectOptions, ObjectRule, ReferenceTo } from "sanity";
3
3
  import * as react1 from "react";
4
+ type PreviewCtx = {
5
+ kind?: string;
6
+ email?: string;
7
+ phone?: string;
8
+ fileName?: string;
9
+ customText?: string;
10
+ externalUrl?: string;
11
+ internalUri?: string;
12
+ internalTitle?: string;
13
+ };
4
14
  /** @public */
5
15
  declare function selectLinkPreview(namespace?: string): {
6
16
  readonly kind: "kind" | `${string}.kind`;
@@ -22,16 +32,7 @@ declare function prepareLinkPreview({
22
32
  internalUri,
23
33
  externalUrl,
24
34
  internalTitle
25
- }: {
26
- kind?: string;
27
- email?: string;
28
- phone?: string;
29
- fileName?: string;
30
- customText?: string;
31
- externalUrl?: string;
32
- internalUri?: string;
33
- internalTitle?: string;
34
- }): {
35
+ }: PreviewCtx): {
35
36
  title: string;
36
37
  subtitle: string | undefined;
37
38
  media: () => react1.JSX.Element;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,16 @@
1
1
  import * as sanity0 from "sanity";
2
2
  import { ObjectDefinition, ObjectOptions, ObjectRule, ReferenceTo } from "sanity";
3
3
  import * as react1 from "react";
4
+ type PreviewCtx = {
5
+ kind?: string;
6
+ email?: string;
7
+ phone?: string;
8
+ fileName?: string;
9
+ customText?: string;
10
+ externalUrl?: string;
11
+ internalUri?: string;
12
+ internalTitle?: string;
13
+ };
4
14
  /** @public */
5
15
  declare function selectLinkPreview(namespace?: string): {
6
16
  readonly kind: "kind" | `${string}.kind`;
@@ -22,16 +32,7 @@ declare function prepareLinkPreview({
22
32
  internalUri,
23
33
  externalUrl,
24
34
  internalTitle
25
- }: {
26
- kind?: string;
27
- email?: string;
28
- phone?: string;
29
- fileName?: string;
30
- customText?: string;
31
- externalUrl?: string;
32
- internalUri?: string;
33
- internalTitle?: string;
34
- }): {
35
+ }: PreviewCtx): {
35
36
  title: string;
36
37
  subtitle: string | undefined;
37
38
  media: () => react1.JSX.Element;
package/dist/index.js CHANGED
@@ -180,7 +180,9 @@ const typeName = "wild.link", LinkKind = {
180
180
  name: LinkKind.internal,
181
181
  type: "object",
182
182
  ...visibleIfKind(LinkKind.internal),
183
- ...requiredIfKind(LinkKind.internal),
183
+ ...requiredIfKind(LinkKind.internal, {
184
+ path: ["link"]
185
+ }),
184
186
  options: {
185
187
  collapsed: !1,
186
188
  collapsible: !1
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 const extensions = options?.extensions;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n\n // Only show enabled extensions.\n if (!extensions?.includes(\"customText\") && member.name === \"customText\") return null;\n\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 selectLinkPreview(namespace?: string) {\n const ns = namespace ? (`${namespace}.` as const) : \"\";\n\n const kind = \"kind\";\n const email = \"email\";\n const phone = \"phone\";\n const fileName = \"file.asset.originalFilename\";\n const customText = \"customText\";\n const externalUrl = \"external\";\n const internalTitle = \"internal.title\";\n const internalUri = \"internal.uri.current\";\n\n return {\n kind: `${ns}${kind}`,\n email: `${ns}${email}`,\n phone: `${ns}${phone}`,\n fileName: `${ns}${fileName}`,\n customText: `${ns}${customText}`,\n internalUri: `${ns}${internalUri}`,\n externalUrl: `${ns}${externalUrl}`,\n internalTitle: `${ns}${internalTitle}`,\n } as const;\n}\n\n/** @public */\nexport function prepareLinkPreview({\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 const LinkExtension = {\n customText: \"customText\",\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 extensions?: (keyof typeof LinkExtension)[];\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 { prepareLinkPreview, selectLinkPreview } 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: selectLinkPreview(),\n prepare: (props) => prepareLinkPreview(props),\n },\n }),\n ],\n },\n };\n});\n\nfunction requireLink(R: ObjectRule) {\n return R.custom((ctx) => (!ctx?.kind ? { message: \"Select the kind of link.\", path: [\"kind\"] } : true));\n}\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n requireLink,\n selectLinkPreview,\n prepareLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["FieldInput","props","$","_c","extensions","schemaType","options","t0","members","map","member","kind","includes","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","selectLinkPreview","namespace","ns","email","phone","fileName","customText","internalUri","externalUrl","internalTitle","prepareLinkPreview","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","message","path"],"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 const extensions = options?.extensions;\n\n return (\n <Stack space={4}>\n {props.members.map((member: ObjectMember) => {\n if (member.kind !== \"field\") return null;\n\n // Only show enabled extensions.\n if (!extensions?.includes(\"customText\") && member.name === \"customText\") return null;\n\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\ntype PreviewCtx = {\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\n/** @public */\nexport function selectLinkPreview(namespace?: string) {\n const ns = namespace ? (`${namespace}.` as const) : \"\";\n\n const kind = \"kind\";\n const email = \"email\";\n const phone = \"phone\";\n const fileName = \"file.asset.originalFilename\";\n const customText = \"customText\";\n const externalUrl = \"external\";\n const internalTitle = \"internal.title\";\n const internalUri = \"internal.uri.current\";\n\n return {\n kind: `${ns}${kind}`,\n email: `${ns}${email}`,\n phone: `${ns}${phone}`,\n fileName: `${ns}${fileName}`,\n customText: `${ns}${customText}`,\n internalUri: `${ns}${internalUri}`,\n externalUrl: `${ns}${externalUrl}`,\n internalTitle: `${ns}${internalTitle}`,\n } as const satisfies PreviewCtx;\n}\n\n/** @public */\nexport function prepareLinkPreview({\n kind,\n email,\n phone,\n fileName,\n customText,\n internalUri,\n externalUrl,\n internalTitle,\n}: PreviewCtx) {\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 const LinkExtension = {\n customText: \"customText\",\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 extensions?: (keyof typeof LinkExtension)[];\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 { prepareLinkPreview, selectLinkPreview } 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, { path: [\"link\"] }),\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: selectLinkPreview(),\n prepare: (props) => prepareLinkPreview(props),\n },\n }),\n ],\n },\n };\n});\n\nfunction requireLink(R: ObjectRule) {\n return R.custom((ctx) => (!ctx?.kind ? { message: \"Select the kind of link.\", path: [\"kind\"] } : true));\n}\n\nexport {\n wildSanityLinkFieldPlugin,\n typeName,\n LinkKind,\n requireLink,\n selectLinkPreview,\n prepareLinkPreview,\n type PluginConfig,\n type FieldOptions,\n type SectionQueryResult,\n};\n"],"names":["FieldInput","props","$","_c","extensions","schemaType","options","t0","members","map","member","kind","includes","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","selectLinkPreview","namespace","ns","email","phone","fileName","customText","internalUri","externalUrl","internalTitle","prepareLinkPreview","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","path","collapsed","collapsible","field","children","weak","weakReferences","to","internalLinkSchemaTypes","disableNew","initialValue","preview","select","prepare","requireLink","R","custom","ctx","message"],"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.13",
3
+ "version": "0.3.14",
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.11"
25
+ "@madebywild/sanity-utils": "0.3.12"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@sanity/ui": "^3.1",
package/src/index.tsx CHANGED
@@ -72,7 +72,7 @@ const wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {
72
72
  name: LinkKind.internal,
73
73
  type: "object",
74
74
  ...visibleIfKind(LinkKind.internal),
75
- ...requiredIfKind(LinkKind.internal),
75
+ ...requiredIfKind(LinkKind.internal, { path: ["link"] }),
76
76
  options: { collapsed: false, collapsible: false },
77
77
  components: {
78
78
  field: (props) => <>{props.children}</>,
package/src/preview.tsx CHANGED
@@ -1,5 +1,16 @@
1
1
  import type { LinkKind } from "./types";
2
2
 
3
+ type PreviewCtx = {
4
+ kind?: string;
5
+ email?: string;
6
+ phone?: string;
7
+ fileName?: string;
8
+ customText?: string;
9
+ externalUrl?: string;
10
+ internalUri?: string;
11
+ internalTitle?: string;
12
+ };
13
+
3
14
  /** @public */
4
15
  export function selectLinkPreview(namespace?: string) {
5
16
  const ns = namespace ? (`${namespace}.` as const) : "";
@@ -22,7 +33,7 @@ export function selectLinkPreview(namespace?: string) {
22
33
  internalUri: `${ns}${internalUri}`,
23
34
  externalUrl: `${ns}${externalUrl}`,
24
35
  internalTitle: `${ns}${internalTitle}`,
25
- } as const;
36
+ } as const satisfies PreviewCtx;
26
37
  }
27
38
 
28
39
  /** @public */
@@ -35,16 +46,7 @@ export function prepareLinkPreview({
35
46
  internalUri,
36
47
  externalUrl,
37
48
  internalTitle,
38
- }: {
39
- kind?: string;
40
- email?: string;
41
- phone?: string;
42
- fileName?: string;
43
- customText?: string;
44
- externalUrl?: string;
45
- internalUri?: string;
46
- internalTitle?: string;
47
- }) {
49
+ }: PreviewCtx) {
48
50
  switch (kind as keyof typeof LinkKind) {
49
51
  case "internal": {
50
52
  return {