@madebywild/sanity-link-field 0.3.10 → 0.3.12
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 +20 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +20 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.tsx +5 -15
- package/src/input.tsx +5 -1
- package/src/preview.tsx +26 -1
- package/src/types.tsx +6 -1
package/dist/index.cjs
CHANGED
|
@@ -18,9 +18,9 @@ function _interopNamespaceCompat(e) {
|
|
|
18
18
|
}
|
|
19
19
|
var changeCase__namespace = /* @__PURE__ */ _interopNamespaceCompat(changeCase), React__namespace = /* @__PURE__ */ _interopNamespaceCompat(React);
|
|
20
20
|
function FieldInput(props) {
|
|
21
|
-
const $ = compilerRuntime.c(5),
|
|
21
|
+
const $ = compilerRuntime.c(5), extensions = props.schemaType.options?.extensions;
|
|
22
22
|
let t0;
|
|
23
|
-
$[0] !==
|
|
23
|
+
$[0] !== extensions || $[1] !== props ? (t0 = props.members.map((member) => member.kind !== "field" || !extensions?.includes("customText") && member.name === "customText" ? null : /* @__PURE__ */ jsxRuntime.jsx(sanity.MemberField, { member, ...props }, member.key)), $[0] = extensions, $[1] = props, $[2] = t0) : t0 = $[2];
|
|
24
24
|
let t1;
|
|
25
25
|
return $[3] !== t0 ? (t1 = /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 4, children: t0 }), $[3] = t0, $[4] = t1) : t1 = $[4], t1;
|
|
26
26
|
}
|
|
@@ -60,7 +60,20 @@ function InternalLinkInput(props) {
|
|
|
60
60
|
}) => /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { as: "button", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 2, children: changeCase__namespace.capitalCase(label ?? value_1) }) }) }) })
|
|
61
61
|
] });
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function selectLinkPreview(namespace) {
|
|
64
|
+
const ns = namespace ? `${namespace}.` : "";
|
|
65
|
+
return {
|
|
66
|
+
kind: `${ns}kind`,
|
|
67
|
+
email: `${ns}email`,
|
|
68
|
+
phone: `${ns}phone`,
|
|
69
|
+
fileName: `${ns}file.asset.originalFilename`,
|
|
70
|
+
customText: `${ns}customText`,
|
|
71
|
+
internalUri: `${ns}internal.uri.current`,
|
|
72
|
+
externalUrl: `${ns}external`,
|
|
73
|
+
internalTitle: `${ns}internal.title`
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function prepareLinkPreview({
|
|
64
77
|
kind,
|
|
65
78
|
email,
|
|
66
79
|
phone,
|
|
@@ -229,17 +242,8 @@ const typeName = "wild.link", LinkKind = {
|
|
|
229
242
|
...visibleIfKind([LinkKind.external, LinkKind.internal])
|
|
230
243
|
})],
|
|
231
244
|
preview: {
|
|
232
|
-
select:
|
|
233
|
-
|
|
234
|
-
email: "email",
|
|
235
|
-
phone: "phone",
|
|
236
|
-
customText: "customText",
|
|
237
|
-
fileName: "file.asset.originalFilename",
|
|
238
|
-
externalUrl: "external",
|
|
239
|
-
internalUri: "internal.uri.current",
|
|
240
|
-
internalTitle: "internal.title"
|
|
241
|
-
},
|
|
242
|
-
prepare: (props) => buildLinkPreview(props)
|
|
245
|
+
select: selectLinkPreview(),
|
|
246
|
+
prepare: (props) => prepareLinkPreview(props)
|
|
243
247
|
}
|
|
244
248
|
})]
|
|
245
249
|
}
|
|
@@ -251,8 +255,9 @@ function requireLink(R) {
|
|
|
251
255
|
});
|
|
252
256
|
}
|
|
253
257
|
exports.LinkKind = LinkKind;
|
|
254
|
-
exports.
|
|
258
|
+
exports.prepareLinkPreview = prepareLinkPreview;
|
|
255
259
|
exports.requireLink = requireLink;
|
|
260
|
+
exports.selectLinkPreview = selectLinkPreview;
|
|
256
261
|
exports.typeName = typeName;
|
|
257
262
|
exports.wildSanityLinkFieldPlugin = wildSanityLinkFieldPlugin;
|
|
258
263
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 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 ? { message: \"Select the kind of link.\", path: [\"kind\"] } : 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","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\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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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,18 @@ import * as sanity0 from "sanity";
|
|
|
2
2
|
import { ObjectDefinition, ObjectOptions, ObjectRule, ReferenceTo } from "sanity";
|
|
3
3
|
import * as react1 from "react";
|
|
4
4
|
/** @public */
|
|
5
|
-
declare function
|
|
5
|
+
declare function selectLinkPreview(namespace?: string): {
|
|
6
|
+
readonly kind: "kind" | `${string}.kind`;
|
|
7
|
+
readonly email: "email" | `${string}.email`;
|
|
8
|
+
readonly phone: "phone" | `${string}.phone`;
|
|
9
|
+
readonly fileName: "file.asset.originalFilename" | `${string}.file.asset.originalFilename`;
|
|
10
|
+
readonly customText: "customText" | `${string}.customText`;
|
|
11
|
+
readonly internalUri: "internal.uri.current" | `${string}.internal.uri.current`;
|
|
12
|
+
readonly externalUrl: "external" | `${string}.external`;
|
|
13
|
+
readonly internalTitle: "internal.title" | `${string}.internal.title`;
|
|
14
|
+
};
|
|
15
|
+
/** @public */
|
|
16
|
+
declare function prepareLinkPreview({
|
|
6
17
|
kind,
|
|
7
18
|
email,
|
|
8
19
|
phone,
|
|
@@ -46,6 +57,10 @@ declare const LinkKind: {
|
|
|
46
57
|
readonly file: "file";
|
|
47
58
|
};
|
|
48
59
|
/** @public */
|
|
60
|
+
declare const LinkExtension: {
|
|
61
|
+
readonly customText: "customText";
|
|
62
|
+
};
|
|
63
|
+
/** @public */
|
|
49
64
|
type SectionQueryResult = ListItem[];
|
|
50
65
|
/** @public */
|
|
51
66
|
type PluginConfig = {
|
|
@@ -54,7 +69,7 @@ type PluginConfig = {
|
|
|
54
69
|
};
|
|
55
70
|
/** @public */
|
|
56
71
|
type FieldOptions = ObjectOptions & {
|
|
57
|
-
|
|
72
|
+
extensions?: (keyof typeof LinkExtension)[];
|
|
58
73
|
};
|
|
59
74
|
declare module "sanity" {
|
|
60
75
|
interface IntrinsicDefinitions {
|
|
@@ -67,4 +82,4 @@ declare module "sanity" {
|
|
|
67
82
|
/** @public */
|
|
68
83
|
declare const wildSanityLinkFieldPlugin: sanity0.Plugin<PluginConfig>;
|
|
69
84
|
declare function requireLink(R: ObjectRule): ObjectRule;
|
|
70
|
-
export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult,
|
|
85
|
+
export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, prepareLinkPreview, requireLink, selectLinkPreview, typeName, wildSanityLinkFieldPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,18 @@ import * as sanity0 from "sanity";
|
|
|
2
2
|
import { ObjectDefinition, ObjectOptions, ObjectRule, ReferenceTo } from "sanity";
|
|
3
3
|
import * as react1 from "react";
|
|
4
4
|
/** @public */
|
|
5
|
-
declare function
|
|
5
|
+
declare function selectLinkPreview(namespace?: string): {
|
|
6
|
+
readonly kind: "kind" | `${string}.kind`;
|
|
7
|
+
readonly email: "email" | `${string}.email`;
|
|
8
|
+
readonly phone: "phone" | `${string}.phone`;
|
|
9
|
+
readonly fileName: "file.asset.originalFilename" | `${string}.file.asset.originalFilename`;
|
|
10
|
+
readonly customText: "customText" | `${string}.customText`;
|
|
11
|
+
readonly internalUri: "internal.uri.current" | `${string}.internal.uri.current`;
|
|
12
|
+
readonly externalUrl: "external" | `${string}.external`;
|
|
13
|
+
readonly internalTitle: "internal.title" | `${string}.internal.title`;
|
|
14
|
+
};
|
|
15
|
+
/** @public */
|
|
16
|
+
declare function prepareLinkPreview({
|
|
6
17
|
kind,
|
|
7
18
|
email,
|
|
8
19
|
phone,
|
|
@@ -46,6 +57,10 @@ declare const LinkKind: {
|
|
|
46
57
|
readonly file: "file";
|
|
47
58
|
};
|
|
48
59
|
/** @public */
|
|
60
|
+
declare const LinkExtension: {
|
|
61
|
+
readonly customText: "customText";
|
|
62
|
+
};
|
|
63
|
+
/** @public */
|
|
49
64
|
type SectionQueryResult = ListItem[];
|
|
50
65
|
/** @public */
|
|
51
66
|
type PluginConfig = {
|
|
@@ -54,7 +69,7 @@ type PluginConfig = {
|
|
|
54
69
|
};
|
|
55
70
|
/** @public */
|
|
56
71
|
type FieldOptions = ObjectOptions & {
|
|
57
|
-
|
|
72
|
+
extensions?: (keyof typeof LinkExtension)[];
|
|
58
73
|
};
|
|
59
74
|
declare module "sanity" {
|
|
60
75
|
interface IntrinsicDefinitions {
|
|
@@ -67,4 +82,4 @@ declare module "sanity" {
|
|
|
67
82
|
/** @public */
|
|
68
83
|
declare const wildSanityLinkFieldPlugin: sanity0.Plugin<PluginConfig>;
|
|
69
84
|
declare function requireLink(R: ObjectRule): ObjectRule;
|
|
70
|
-
export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult,
|
|
85
|
+
export { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, prepareLinkPreview, requireLink, selectLinkPreview, typeName, wildSanityLinkFieldPlugin };
|
package/dist/index.js
CHANGED
|
@@ -7,9 +7,9 @@ import { Stack, Card, Box, Text } from "@sanity/ui";
|
|
|
7
7
|
import * as changeCase from "change-case";
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
function FieldInput(props) {
|
|
10
|
-
const $ = c(5),
|
|
10
|
+
const $ = c(5), extensions = props.schemaType.options?.extensions;
|
|
11
11
|
let t0;
|
|
12
|
-
$[0] !==
|
|
12
|
+
$[0] !== extensions || $[1] !== props ? (t0 = props.members.map((member) => member.kind !== "field" || !extensions?.includes("customText") && member.name === "customText" ? null : /* @__PURE__ */ jsx(MemberField, { member, ...props }, member.key)), $[0] = extensions, $[1] = props, $[2] = t0) : t0 = $[2];
|
|
13
13
|
let t1;
|
|
14
14
|
return $[3] !== t0 ? (t1 = /* @__PURE__ */ jsx(Stack, { space: 4, children: t0 }), $[3] = t0, $[4] = t1) : t1 = $[4], t1;
|
|
15
15
|
}
|
|
@@ -49,7 +49,20 @@ function InternalLinkInput(props) {
|
|
|
49
49
|
}) => /* @__PURE__ */ jsx(Card, { as: "button", children: /* @__PURE__ */ jsx(Box, { flex: 1, padding: 3, children: /* @__PURE__ */ jsx(Text, { size: 2, children: changeCase.capitalCase(label ?? value_1) }) }) }) })
|
|
50
50
|
] });
|
|
51
51
|
}
|
|
52
|
-
function
|
|
52
|
+
function selectLinkPreview(namespace) {
|
|
53
|
+
const ns = namespace ? `${namespace}.` : "";
|
|
54
|
+
return {
|
|
55
|
+
kind: `${ns}kind`,
|
|
56
|
+
email: `${ns}email`,
|
|
57
|
+
phone: `${ns}phone`,
|
|
58
|
+
fileName: `${ns}file.asset.originalFilename`,
|
|
59
|
+
customText: `${ns}customText`,
|
|
60
|
+
internalUri: `${ns}internal.uri.current`,
|
|
61
|
+
externalUrl: `${ns}external`,
|
|
62
|
+
internalTitle: `${ns}internal.title`
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function prepareLinkPreview({
|
|
53
66
|
kind,
|
|
54
67
|
email,
|
|
55
68
|
phone,
|
|
@@ -218,17 +231,8 @@ const typeName = "wild.link", LinkKind = {
|
|
|
218
231
|
...visibleIfKind([LinkKind.external, LinkKind.internal])
|
|
219
232
|
})],
|
|
220
233
|
preview: {
|
|
221
|
-
select:
|
|
222
|
-
|
|
223
|
-
email: "email",
|
|
224
|
-
phone: "phone",
|
|
225
|
-
customText: "customText",
|
|
226
|
-
fileName: "file.asset.originalFilename",
|
|
227
|
-
externalUrl: "external",
|
|
228
|
-
internalUri: "internal.uri.current",
|
|
229
|
-
internalTitle: "internal.title"
|
|
230
|
-
},
|
|
231
|
-
prepare: (props) => buildLinkPreview(props)
|
|
234
|
+
select: selectLinkPreview(),
|
|
235
|
+
prepare: (props) => prepareLinkPreview(props)
|
|
232
236
|
}
|
|
233
237
|
})]
|
|
234
238
|
}
|
|
@@ -241,8 +245,9 @@ function requireLink(R) {
|
|
|
241
245
|
}
|
|
242
246
|
export {
|
|
243
247
|
LinkKind,
|
|
244
|
-
|
|
248
|
+
prepareLinkPreview,
|
|
245
249
|
requireLink,
|
|
250
|
+
selectLinkPreview,
|
|
246
251
|
typeName,
|
|
247
252
|
wildSanityLinkFieldPlugin
|
|
248
253
|
};
|
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 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 ? { message: \"Select the kind of link.\", path: [\"kind\"] } : 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","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\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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@madebywild/sanity-link-field",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
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.
|
|
25
|
+
"@madebywild/sanity-utils": "0.3.10"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@sanity/ui": "^3.1",
|
package/src/index.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { requiredIf, visibleIf } from "@madebywild/sanity-utils";
|
|
|
2
2
|
import type { ObjectRule } from "sanity";
|
|
3
3
|
import { defineField, definePlugin, defineType } from "sanity";
|
|
4
4
|
import { FieldInput, InternalLinkInput } from "./input";
|
|
5
|
-
import {
|
|
5
|
+
import { prepareLinkPreview, selectLinkPreview } from "./preview";
|
|
6
6
|
import { type FieldOptions, LinkKind, type PluginConfig, type SectionQueryResult, typeName } from "./types";
|
|
7
7
|
|
|
8
8
|
const visibleIfKind = visibleIf("kind");
|
|
@@ -123,19 +123,8 @@ const wildSanityLinkFieldPlugin = definePlugin<PluginConfig>((config) => {
|
|
|
123
123
|
}),
|
|
124
124
|
],
|
|
125
125
|
preview: {
|
|
126
|
-
select:
|
|
127
|
-
|
|
128
|
-
email: "email",
|
|
129
|
-
phone: "phone",
|
|
130
|
-
customText: "customText",
|
|
131
|
-
fileName: "file.asset.originalFilename",
|
|
132
|
-
externalUrl: "external",
|
|
133
|
-
internalUri: "internal.uri.current",
|
|
134
|
-
internalTitle: "internal.title",
|
|
135
|
-
},
|
|
136
|
-
prepare: (props) => {
|
|
137
|
-
return buildLinkPreview(props);
|
|
138
|
-
},
|
|
126
|
+
select: selectLinkPreview(),
|
|
127
|
+
prepare: (props) => prepareLinkPreview(props),
|
|
139
128
|
},
|
|
140
129
|
}),
|
|
141
130
|
],
|
|
@@ -152,7 +141,8 @@ export {
|
|
|
152
141
|
typeName,
|
|
153
142
|
LinkKind,
|
|
154
143
|
requireLink,
|
|
155
|
-
|
|
144
|
+
selectLinkPreview,
|
|
145
|
+
prepareLinkPreview,
|
|
156
146
|
type PluginConfig,
|
|
157
147
|
type FieldOptions,
|
|
158
148
|
type SectionQueryResult,
|
package/src/input.tsx
CHANGED
|
@@ -9,12 +9,16 @@ import type { FieldOptions } from "./types";
|
|
|
9
9
|
|
|
10
10
|
function FieldInput(props: ObjectInputProps) {
|
|
11
11
|
const options = props.schemaType.options as FieldOptions | undefined;
|
|
12
|
+
const extensions = options?.extensions;
|
|
12
13
|
|
|
13
14
|
return (
|
|
14
15
|
<Stack space={4}>
|
|
15
16
|
{props.members.map((member: ObjectMember) => {
|
|
16
17
|
if (member.kind !== "field") return null;
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
// Only show enabled extensions.
|
|
20
|
+
if (!extensions?.includes("customText") && member.name === "customText") return null;
|
|
21
|
+
|
|
18
22
|
return <MemberField key={member.key} member={member} {...props} />;
|
|
19
23
|
})}
|
|
20
24
|
</Stack>
|
package/src/preview.tsx
CHANGED
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
import type { LinkKind } from "./types";
|
|
2
2
|
|
|
3
3
|
/** @public */
|
|
4
|
-
export function
|
|
4
|
+
export function selectLinkPreview(namespace?: string) {
|
|
5
|
+
const ns = namespace ? (`${namespace}.` as const) : "";
|
|
6
|
+
|
|
7
|
+
const kind = "kind";
|
|
8
|
+
const email = "email";
|
|
9
|
+
const phone = "phone";
|
|
10
|
+
const fileName = "file.asset.originalFilename";
|
|
11
|
+
const customText = "customText";
|
|
12
|
+
const externalUrl = "external";
|
|
13
|
+
const internalTitle = "internal.title";
|
|
14
|
+
const internalUri = "internal.uri.current";
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
kind: `${ns}${kind}`,
|
|
18
|
+
email: `${ns}${email}`,
|
|
19
|
+
phone: `${ns}${phone}`,
|
|
20
|
+
fileName: `${ns}${fileName}`,
|
|
21
|
+
customText: `${ns}${customText}`,
|
|
22
|
+
internalUri: `${ns}${internalUri}`,
|
|
23
|
+
externalUrl: `${ns}${externalUrl}`,
|
|
24
|
+
internalTitle: `${ns}${internalTitle}`,
|
|
25
|
+
} as const;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @public */
|
|
29
|
+
export function prepareLinkPreview({
|
|
5
30
|
kind,
|
|
6
31
|
email,
|
|
7
32
|
phone,
|
package/src/types.tsx
CHANGED
|
@@ -13,6 +13,11 @@ export const LinkKind = {
|
|
|
13
13
|
file: "file",
|
|
14
14
|
} as const;
|
|
15
15
|
|
|
16
|
+
/** @public */
|
|
17
|
+
export const LinkExtension = {
|
|
18
|
+
customText: "customText",
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
16
21
|
/** @public */
|
|
17
22
|
export type SectionQueryResult = ListItem[];
|
|
18
23
|
|
|
@@ -24,7 +29,7 @@ export type PluginConfig = {
|
|
|
24
29
|
|
|
25
30
|
/** @public */
|
|
26
31
|
export type FieldOptions = ObjectOptions & {
|
|
27
|
-
|
|
32
|
+
extensions?: (keyof typeof LinkExtension)[];
|
|
28
33
|
};
|
|
29
34
|
|
|
30
35
|
// Add the custom field definition to Sanity's intrinsic definitions
|