@madebywild/sanity-richtext-field 0.1.37 → 1.0.0
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/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/_chunks-cjs/types.cjs +4 -0
- package/dist/_chunks-cjs/types.cjs.map +1 -0
- package/dist/_chunks-cjs/utils.cjs +88 -0
- package/dist/_chunks-cjs/utils.cjs.map +1 -0
- package/dist/_chunks-dts/index.d.cts +96 -0
- package/dist/_chunks-dts/index.d.ts +96 -0
- package/dist/_chunks-es/types.js +5 -0
- package/dist/_chunks-es/types.js.map +1 -0
- package/dist/_chunks-es/utils.js +90 -0
- package/dist/_chunks-es/utils.js.map +1 -0
- package/dist/blocks/media-block.cjs +40 -0
- package/dist/blocks/media-block.cjs.map +1 -0
- package/dist/blocks/media-block.d.cts +19 -0
- package/dist/blocks/media-block.d.ts +19 -0
- package/dist/blocks/media-block.js +43 -0
- package/dist/blocks/media-block.js.map +1 -0
- package/dist/blocks/media-grid-block.cjs +56 -0
- package/dist/blocks/media-grid-block.cjs.map +1 -0
- package/dist/blocks/media-grid-block.d.cts +24 -0
- package/dist/blocks/media-grid-block.d.ts +24 -0
- package/dist/blocks/media-grid-block.js +60 -0
- package/dist/blocks/media-grid-block.js.map +1 -0
- package/dist/blocks/media-only-block.cjs +42 -0
- package/dist/blocks/media-only-block.cjs.map +1 -0
- package/dist/blocks/media-only-block.d.cts +24 -0
- package/dist/blocks/media-only-block.d.ts +24 -0
- package/dist/blocks/media-only-block.js +46 -0
- package/dist/blocks/media-only-block.js.map +1 -0
- package/dist/blocks/media-slider-block.cjs +56 -0
- package/dist/blocks/media-slider-block.cjs.map +1 -0
- package/dist/blocks/media-slider-block.d.cts +24 -0
- package/dist/blocks/media-slider-block.d.ts +24 -0
- package/dist/blocks/media-slider-block.js +60 -0
- package/dist/blocks/media-slider-block.js.map +1 -0
- package/dist/blocks/quote-block.cjs +42 -0
- package/dist/blocks/quote-block.cjs.map +1 -0
- package/dist/blocks/quote-block.d.cts +17 -0
- package/dist/blocks/quote-block.d.ts +17 -0
- package/dist/blocks/quote-block.js +47 -0
- package/dist/blocks/quote-block.js.map +1 -0
- package/dist/index.cjs +113 -338
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -139
- package/dist/index.d.ts +21 -139
- package/dist/index.js +113 -339
- package/dist/index.js.map +1 -1
- package/dist/parts.cjs +221 -0
- package/dist/parts.cjs.map +1 -0
- package/dist/parts.d.cts +96 -0
- package/dist/parts.d.ts +96 -0
- package/dist/parts.js +210 -0
- package/dist/parts.js.map +1 -0
- package/dist/utils.cjs +5 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +18 -0
- package/dist/utils.d.ts +18 -0
- package/dist/utils.js +5 -0
- package/dist/utils.js.map +1 -0
- package/package.json +40 -8
- package/src/blocks/media-grid-block.tsx +79 -0
- package/src/blocks/media-only-block.tsx +58 -0
- package/src/blocks/media-slider-block.tsx +79 -0
- package/src/blocks/quote-block.tsx +47 -0
- package/src/index.tsx +28 -23
- package/src/input.tsx +125 -99
- package/src/internal-utils.tsx +114 -0
- package/src/parts/annotations/color.tsx +3 -2
- package/src/parts/annotations/index.tsx +6 -5
- package/src/parts/decorators/index.tsx +6 -6
- package/src/parts/index.tsx +6 -25
- package/src/parts/lists/index.tsx +6 -4
- package/src/parts/spans/index.tsx +6 -4
- package/src/parts/spans/media.tsx +6 -4
- package/src/parts/styles/index.tsx +6 -5
- package/src/presets.tsx +12 -4
- package/src/types.tsx +29 -16
- package/src/utils.ts +1 -0
- package/src/parts/blocks/index.tsx +0 -5
- package/src/parts/blocks/media-block.tsx +0 -29
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Made by Wild
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1 +1,70 @@
|
|
|
1
|
+
> [!IMPORTANT]
|
|
2
|
+
> This package is primarily intended for internal use.
|
|
3
|
+
|
|
1
4
|
# @madebywild/sanity-richtext-field
|
|
5
|
+
|
|
6
|
+
Rich text field plugin with configurable blocks, marks, and presets.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @madebywild/sanity-richtext-field
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configure Plugin
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { wildSanityRichtextFieldPlugin } from "@madebywild/sanity-richtext-field";
|
|
19
|
+
import {
|
|
20
|
+
createAnnotations,
|
|
21
|
+
createDecorators,
|
|
22
|
+
createLists,
|
|
23
|
+
createStyles,
|
|
24
|
+
} from "@madebywild/sanity-richtext-field/parts";
|
|
25
|
+
import { createBlock as quoteBlock } from "@madebywild/sanity-richtext-field/blocks/quote-block";
|
|
26
|
+
import { createBlock } from "@madebywild/sanity-richtext-field/utils";
|
|
27
|
+
|
|
28
|
+
const customBlock = defineField({
|
|
29
|
+
name: "customBlockTest",
|
|
30
|
+
type: "object",
|
|
31
|
+
fields: [
|
|
32
|
+
defineField({
|
|
33
|
+
name: "title",
|
|
34
|
+
type: "string",
|
|
35
|
+
title: "Title",
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export default defineConfig({
|
|
41
|
+
plugins: [
|
|
42
|
+
wildSanityRichtextFieldPlugin({
|
|
43
|
+
blocks: [createBlock(customBlock), quoteBlock()],
|
|
44
|
+
styles: [...createStyles() /* Add your own */],
|
|
45
|
+
lists: [...createLists() /* Add your own */],
|
|
46
|
+
decorators: [...createDecorators() /* Add your own */],
|
|
47
|
+
annotations: [...createAnnotations() /* Add your own */],
|
|
48
|
+
}),
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Use in Schema
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
defineField({
|
|
57
|
+
name: "body",
|
|
58
|
+
type: "wild.richtext",
|
|
59
|
+
options: {
|
|
60
|
+
// Presets are collections of options that can be used to configure the field.
|
|
61
|
+
preset: "full",
|
|
62
|
+
// Whitelist / Blacklist features.
|
|
63
|
+
// By default, the field comes with NO features enabled.
|
|
64
|
+
allowedKinds: ["styles", "lists", "decorators", "annotations"],
|
|
65
|
+
allowedParts: ["wild.richtext.annotations.bold"],
|
|
66
|
+
disallowedKinds: ["styles", "lists", "decorators", "annotations"],
|
|
67
|
+
disallowedParts: ["wild.richtext.annotations.bold"],
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.cjs","sources":["../../src/types.tsx"],"sourcesContent":["import type {\n ArrayDefinition,\n ArrayOfType,\n ArrayOptions,\n BlockDecoratorDefinition,\n BlockListDefinition,\n BlockStyleDefinition,\n} from \"sanity\";\n\n/** @public */\nconst typeName = \"wild.richtext\" as const;\n\ntype RichtextConfig = {\n /**\n * Custom block types to include in the richtext field.\n */\n blocks?: ArrayOfType<\"object\">[];\n /**\n * Custom inline object types to include in the richtext field.\n */\n spans?: ArrayOfType<\"object\">[];\n /**\n * Custom styles to include in the richtext field.\n */\n styles?: BlockStyleDefinition[];\n /**\n * Custom lists to include in the richtext field.\n */\n lists?: BlockListDefinition[];\n /**\n * Custom annotations to include in the richtext field.\n */\n annotations?: ArrayOfType<\"object\">[];\n /**\n * Custom decorators to include in the richtext field.\n */\n decorators?: BlockDecoratorDefinition[];\n};\n\n/** @public */\ntype PluginConfig = RichtextConfig & {\n /**\n * Whether spell checking should be enabled in the richtext editor.\n */\n spellCheck?: boolean;\n};\n\ntype Size = \"sm\" | \"lg\";\ntype Kind = \"blocks\" | \"spans\" | \"lists\" | \"styles\" | \"decorators\" | \"annotations\";\n\n// Presets are collections of commonly used field options.\n// They allow to quickly set up the richtext field with a predefined set of options.\n// Users can still override individual options when using a preset.\ntype Preset = \"basic\" | \"full\";\ntype Presets = Record<Preset, Omit<FieldOptions, keyof ArrayOptions | \"preset\">>;\n\n// The user can provide custom dimensions as a string.\n// Or use an existing preset size.\ntype MaybeSize = Size | (string & {});\n\n/** @public */\ntype FieldOptions = ArrayOptions & {\n /**\n * Size of the editor field.\n * This will affect the height of the editor in the Sanity studio.\n */\n size?: MaybeSize;\n /**\n * Preset configuration for the richtext field.\n * Presets are predefined sets of options that can be applied to the field.\n */\n preset?: keyof Presets;\n /**\n * Whether the portable text component is active immediately on page load.\n */\n initiallyActive?: boolean;\n /**\n * Whitelist individual parts by their name.\n * To whitelist a complete set of parts, use the `allowedKinds` property.\n */\n allowedParts?: string[];\n /**\n * Blacklist individual parts by their name.\n * To blacklist a complete set of parts, use the `disallowedKinds` property.\n */\n disallowedParts?: string[];\n /**\n * Whitelist kinds of parts by their name.\n * To whitelist individual parts within kinds, use the `allowedParts` property.\n */\n allowedKinds?: Kind[];\n /**\n * Blacklist kinds of parts by their name.\n * To blacklist individual parts within kinds, use the `disallowedParts` property.\n */\n disallowedKinds?: Kind[];\n};\n\nexport { typeName, type RichtextConfig, type PluginConfig, type Size, type Kind, type Presets, type FieldOptions };\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<ArrayDefinition, \"type\" | \"of\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n"],"names":["typeName"],"mappings":";AAUA,MAAMA,WAAW;;"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity");
|
|
3
|
+
function createBlock(block) {
|
|
4
|
+
const blockPreview = {
|
|
5
|
+
select: {
|
|
6
|
+
...block.preview?.select
|
|
7
|
+
},
|
|
8
|
+
prepare: ({
|
|
9
|
+
customTitle,
|
|
10
|
+
...rest
|
|
11
|
+
}) => {
|
|
12
|
+
const defaultPreview = block.preview?.prepare?.(rest) ?? {};
|
|
13
|
+
return {
|
|
14
|
+
title: block.title ?? "Untitled",
|
|
15
|
+
media: block.icon ?? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u2753" }),
|
|
16
|
+
...defaultPreview
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
return sanity.defineArrayMember({
|
|
21
|
+
...block,
|
|
22
|
+
preview: blockPreview
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function reshapeListKind(entry, findNeedle) {
|
|
26
|
+
const list = entry.type?.options?.list;
|
|
27
|
+
if (!list) return entry;
|
|
28
|
+
const filteredList = list.filter((s) => findNeedle(s.value));
|
|
29
|
+
return {
|
|
30
|
+
...entry,
|
|
31
|
+
type: {
|
|
32
|
+
...entry.type,
|
|
33
|
+
options: {
|
|
34
|
+
...entry.type.options,
|
|
35
|
+
list: filteredList
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function reshapeOfKind(entry, findNeedle) {
|
|
41
|
+
const list = entry.type?.of;
|
|
42
|
+
if (!list) return entry;
|
|
43
|
+
const filteredOf = list.filter((a) => findNeedle(a.name));
|
|
44
|
+
return {
|
|
45
|
+
...entry,
|
|
46
|
+
type: {
|
|
47
|
+
...entry.type,
|
|
48
|
+
of: filteredOf
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function uniqBy(items, key) {
|
|
53
|
+
const seen = /* @__PURE__ */ new Set(), out = [];
|
|
54
|
+
for (const item of items) {
|
|
55
|
+
const k = key(item);
|
|
56
|
+
seen.has(k) || (seen.add(k), out.push(item));
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
function createAllowFilter({
|
|
61
|
+
label,
|
|
62
|
+
allowed,
|
|
63
|
+
disallowed,
|
|
64
|
+
defaultBehavior = "disallow"
|
|
65
|
+
}) {
|
|
66
|
+
const hasAllowed = allowed !== void 0, hasDisallowed = disallowed !== void 0;
|
|
67
|
+
hasAllowed && hasDisallowed && console.warn(`Wild Sanity Rich Text Field: Both \`allowed${label}\` and \`disallowed${label}\` are set. \`allowed${label}\` will take precedence.`);
|
|
68
|
+
const allowedSet = hasAllowed ? new Set(allowed) : null, disallowedSet = !allowedSet && hasDisallowed ? new Set(disallowed) : null;
|
|
69
|
+
return {
|
|
70
|
+
isAllowed(value) {
|
|
71
|
+
return allowedSet ? allowedSet.has(value) : disallowedSet ? !disallowedSet.has(value) : defaultBehavior === "allow";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const sizeToHeightMap = {
|
|
76
|
+
sm: "10rem",
|
|
77
|
+
lg: "50vh"
|
|
78
|
+
};
|
|
79
|
+
function getHeight(size) {
|
|
80
|
+
return size in sizeToHeightMap ? sizeToHeightMap[size] : size;
|
|
81
|
+
}
|
|
82
|
+
exports.createAllowFilter = createAllowFilter;
|
|
83
|
+
exports.createBlock = createBlock;
|
|
84
|
+
exports.getHeight = getHeight;
|
|
85
|
+
exports.reshapeListKind = reshapeListKind;
|
|
86
|
+
exports.reshapeOfKind = reshapeOfKind;
|
|
87
|
+
exports.uniqBy = uniqBy;
|
|
88
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../src/internal-utils.tsx"],"sourcesContent":["import { type ArraySchemaType, defineArrayMember, type ObjectDefinition, type ObjectField } from \"sanity\";\nimport type { Size } from \"./types\";\n\n/**\n * Creates a schema definition for a new richtext block.\n * @public\n */\nfunction createBlock(block: ObjectDefinition) {\n const blockPreview = {\n select: {\n ...block.preview?.select,\n },\n prepare: ({ customTitle, ...rest }: Record<string, string>) => {\n const defaultPreview = block.preview?.prepare?.(rest) ?? {};\n\n return {\n title: block.title ?? \"Untitled\",\n media: block.icon ?? <>❓</>,\n ...defaultPreview,\n };\n },\n };\n\n return defineArrayMember({\n ...block,\n preview: blockPreview,\n });\n}\n\n/**\n * Reshapes the list kind of an array field.\n */\nfunction reshapeListKind<E extends ObjectField<ArraySchemaType>>(entry: E, findNeedle: (needle: string) => boolean) {\n const list = entry.type?.options?.list;\n if (!list) return entry;\n const filteredList = list.filter((s) => findNeedle((s as { value: string }).value));\n return { ...entry, type: { ...entry.type, options: { ...entry.type.options, list: filteredList } } };\n}\n\n/**\n * Reshapes the of kind of an array field.\n */\nfunction reshapeOfKind<E extends ObjectField<ArraySchemaType>>(entry: E, findNeedle: (needle: string) => boolean) {\n const list = entry.type?.of;\n if (!list) return entry;\n const filteredOf = list.filter((a: { name: string }) => findNeedle(a.name));\n return { ...entry, type: { ...entry.type, of: filteredOf } };\n}\n\n/**\n * Removes duplicates from an array based on a key function.\n */\nfunction uniqBy<T>(items: T[], key: (t: T) => string): T[] {\n const seen = new Set<string>();\n const out: T[] = [];\n for (const item of items) {\n const k = key(item);\n if (seen.has(k)) continue;\n seen.add(k);\n out.push(item);\n }\n return out;\n}\n\n/**\n * Creates a filter function that allows or disallows values based on a list of allowed or disallowed values.\n */\nfunction createAllowFilter<T extends string>({\n label,\n allowed,\n disallowed,\n defaultBehavior = \"disallow\",\n}: {\n label: string;\n allowed?: readonly T[];\n disallowed?: readonly T[];\n defaultBehavior?: \"allow\" | \"disallow\";\n}) {\n const hasAllowed = allowed !== undefined;\n const hasDisallowed = disallowed !== undefined;\n\n if (hasAllowed && hasDisallowed) {\n console.warn(\n `Wild Sanity Rich Text Field: Both \\`allowed${label}\\` and \\`disallowed${label}\\` are set. \\`allowed${label}\\` will take precedence.`\n );\n }\n\n const allowedSet = hasAllowed ? new Set(allowed) : null;\n const disallowedSet = !allowedSet && hasDisallowed ? new Set(disallowed) : null;\n\n return {\n isAllowed(value: T) {\n if (allowedSet) return allowedSet.has(value);\n if (disallowedSet) return !disallowedSet.has(value);\n return defaultBehavior === \"allow\";\n },\n };\n}\n\nconst sizeToHeightMap = {\n sm: \"10rem\",\n lg: \"50vh\",\n} as const satisfies Record<Size, string>;\n\n/**\n * Retrieves the height value for a given size.\n * If the value is not part of the predefined sizes, assume\n * its a raw size string (e.g., \"200px\") and use it as is.\n */\nfunction getHeight(size: string) {\n return size in sizeToHeightMap ? sizeToHeightMap[size as keyof typeof sizeToHeightMap] : size;\n}\n\nexport { createBlock, createAllowFilter, uniqBy, reshapeListKind, reshapeOfKind, getHeight };\n"],"names":["createBlock","block","blockPreview","select","preview","prepare","customTitle","rest","defaultPreview","title","media","icon","jsx","Fragment","defineArrayMember","reshapeListKind","entry","findNeedle","list","type","options","filteredList","filter","s","value","reshapeOfKind","of","filteredOf","a","name","uniqBy","items","key","seen","Set","out","item","k","has","add","push","createAllowFilter","label","allowed","disallowed","defaultBehavior","hasAllowed","undefined","hasDisallowed","console","warn","allowedSet","disallowedSet","isAllowed","sizeToHeightMap","sm","lg","getHeight","size"],"mappings":";;AAOA,SAASA,YAAYC,OAAyB;AAC5C,QAAMC,eAAe;AAAA,IACnBC,QAAQ;AAAA,MACN,GAAGF,MAAMG,SAASD;AAAAA,IAAAA;AAAAA,IAEpBE,SAASA,CAAC;AAAA,MAAEC;AAAAA,MAAa,GAAGC;AAAAA,IAAAA,MAAmC;AAC7D,YAAMC,iBAAiBP,MAAMG,SAASC,UAAUE,IAAI,KAAK,CAAA;AAEzD,aAAO;AAAA,QACLE,OAAOR,MAAMQ,SAAS;AAAA,QACtBC,OAAOT,MAAMU,QAAQC,2BAAAA,IAAAC,WAAAA,UAAA,EAAE,UAAA,UAAC;AAAA,QACxB,GAAGL;AAAAA,MAAAA;AAAAA,IAEP;AAAA,EAAA;AAGF,SAAOM,yBAAkB;AAAA,IACvB,GAAGb;AAAAA,IACHG,SAASF;AAAAA,EAAAA,CACV;AACH;AAKA,SAASa,gBAAwDC,OAAUC,YAAyC;AAClH,QAAMC,OAAOF,MAAMG,MAAMC,SAASF;AAClC,MAAI,CAACA,KAAM,QAAOF;AAClB,QAAMK,eAAeH,KAAKI,OAAQC,OAAMN,WAAYM,EAAwBC,KAAK,CAAC;AAClF,SAAO;AAAA,IAAE,GAAGR;AAAAA,IAAOG,MAAM;AAAA,MAAE,GAAGH,MAAMG;AAAAA,MAAMC,SAAS;AAAA,QAAE,GAAGJ,MAAMG,KAAKC;AAAAA,QAASF,MAAMG;AAAAA,MAAAA;AAAAA,IAAa;AAAA,EAAE;AACnG;AAKA,SAASI,cAAsDT,OAAUC,YAAyC;AAChH,QAAMC,OAAOF,MAAMG,MAAMO;AACzB,MAAI,CAACR,KAAM,QAAOF;AAClB,QAAMW,aAAaT,KAAKI,OAAQM,OAAwBX,WAAWW,EAAEC,IAAI,CAAC;AAC1E,SAAO;AAAA,IAAE,GAAGb;AAAAA,IAAOG,MAAM;AAAA,MAAE,GAAGH,MAAMG;AAAAA,MAAMO,IAAIC;AAAAA,IAAAA;AAAAA,EAAW;AAC3D;AAKA,SAASG,OAAUC,OAAYC,KAA4B;AACzD,QAAMC,OAAO,oBAAIC,IAAAA,GACXC,MAAW,CAAA;AACjB,aAAWC,QAAQL,OAAO;AACxB,UAAMM,IAAIL,IAAII,IAAI;AACdH,SAAKK,IAAID,CAAC,MACdJ,KAAKM,IAAIF,CAAC,GACVF,IAAIK,KAAKJ,IAAI;AAAA,EACf;AACA,SAAOD;AACT;AAKA,SAASM,kBAAoC;AAAA,EAC3CC;AAAAA,EACAC;AAAAA,EACAC;AAAAA,EACAC,kBAAkB;AAMpB,GAAG;AACD,QAAMC,aAAaH,YAAYI,QACzBC,gBAAgBJ,eAAeG;AAEjCD,gBAAcE,iBAChBC,QAAQC,KACN,8CAA8CR,KAAK,sBAAsBA,KAAK,wBAAwBA,KAAK,0BAC7G;AAGF,QAAMS,aAAaL,aAAa,IAAIZ,IAAIS,OAAO,IAAI,MAC7CS,gBAAgB,CAACD,cAAcH,gBAAgB,IAAId,IAAIU,UAAU,IAAI;AAE3E,SAAO;AAAA,IACLS,UAAU7B,OAAU;AAClB,aAAI2B,aAAmBA,WAAWb,IAAId,KAAK,IACvC4B,gBAAsB,CAACA,cAAcd,IAAId,KAAK,IAC3CqB,oBAAoB;AAAA,IAC7B;AAAA,EAAA;AAEJ;AAEA,MAAMS,kBAAkB;AAAA,EACtBC,IAAI;AAAA,EACJC,IAAI;AACN;AAOA,SAASC,UAAUC,MAAc;AAC/B,SAAOA,QAAQJ,kBAAkBA,gBAAgBI,IAAI,IAAoCA;AAC3F;;;;;;;"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as sanity36 from "sanity";
|
|
2
|
+
import * as react22 from "react";
|
|
3
|
+
/** @public */
|
|
4
|
+
declare function createAnnotations(): readonly [{
|
|
5
|
+
type: "wild.link";
|
|
6
|
+
name: "wild.richtext.annotation.link";
|
|
7
|
+
} & sanity36.TypeAliasDefinition<"wild.link", "string" | "number" | "boolean" | "object" | "wild.richtext" | "wild.media" | "array" | "block" | "date" | "datetime" | "document" | "file" | "geopoint" | "image" | "reference" | "crossDatasetReference" | "globalDocumentReference" | "slug" | "text" | "url" | "email" | undefined> & {
|
|
8
|
+
preview?: sanity36.PreviewConfig<Record<string, string>, Record<never, any>> | undefined;
|
|
9
|
+
} & sanity36.FieldDefinitionBase & sanity36.WidenValidation & sanity36.WidenInitialValue, {
|
|
10
|
+
type: "object";
|
|
11
|
+
name: "wild.richtext.annotation.textColor";
|
|
12
|
+
} & Omit<sanity36.ObjectDefinition, "preview"> & {
|
|
13
|
+
preview?: sanity36.PreviewConfig<Record<string, string>, Record<never, any>> | undefined;
|
|
14
|
+
} & sanity36.FieldDefinitionBase & sanity36.WidenValidation & sanity36.WidenInitialValue, {
|
|
15
|
+
type: "object";
|
|
16
|
+
name: "wild.richtext.annotation.highlightColor";
|
|
17
|
+
} & Omit<sanity36.ObjectDefinition, "preview"> & {
|
|
18
|
+
preview?: sanity36.PreviewConfig<Record<string, string>, Record<never, any>> | undefined;
|
|
19
|
+
} & sanity36.FieldDefinitionBase & sanity36.WidenValidation & sanity36.WidenInitialValue];
|
|
20
|
+
/** @public */
|
|
21
|
+
declare function createDecorators(): readonly [{
|
|
22
|
+
readonly title: "Strong";
|
|
23
|
+
readonly value: "wild.richtext.decorator.strong";
|
|
24
|
+
readonly icon: react22.ForwardRefExoticComponent<Omit<react22.SVGProps<SVGSVGElement>, "ref"> & react22.RefAttributes<SVGSVGElement>>;
|
|
25
|
+
readonly component: ({
|
|
26
|
+
children
|
|
27
|
+
}: BlockDecoratorProps) => react22.JSX.Element;
|
|
28
|
+
}, {
|
|
29
|
+
readonly title: "Emphasis";
|
|
30
|
+
readonly value: "wild.richtext.decorator.em";
|
|
31
|
+
readonly icon: react22.ForwardRefExoticComponent<Omit<react22.SVGProps<SVGSVGElement>, "ref"> & react22.RefAttributes<SVGSVGElement>>;
|
|
32
|
+
readonly component: ({
|
|
33
|
+
children
|
|
34
|
+
}: BlockDecoratorProps) => react22.JSX.Element;
|
|
35
|
+
}, {
|
|
36
|
+
readonly title: "Code";
|
|
37
|
+
readonly value: "wild.richtext.decorator.code";
|
|
38
|
+
readonly icon: react22.ForwardRefExoticComponent<Omit<react22.SVGProps<SVGSVGElement>, "ref"> & react22.RefAttributes<SVGSVGElement>>;
|
|
39
|
+
readonly component: ({
|
|
40
|
+
children
|
|
41
|
+
}: BlockDecoratorProps) => react22.JSX.Element;
|
|
42
|
+
}, {
|
|
43
|
+
readonly title: "Sup";
|
|
44
|
+
readonly value: "wild.richtext.decorator.sup";
|
|
45
|
+
readonly icon: () => react22.JSX.Element;
|
|
46
|
+
readonly component: ({
|
|
47
|
+
children
|
|
48
|
+
}: BlockDecoratorProps) => react22.JSX.Element;
|
|
49
|
+
}];
|
|
50
|
+
/** @public */
|
|
51
|
+
declare function createLists(): readonly [{
|
|
52
|
+
readonly title: "Bullet";
|
|
53
|
+
readonly value: "wild.richtext.list.bullet";
|
|
54
|
+
readonly icon: react22.ForwardRefExoticComponent<Omit<react22.SVGProps<SVGSVGElement>, "ref"> & react22.RefAttributes<SVGSVGElement>>;
|
|
55
|
+
}, {
|
|
56
|
+
readonly title: "Number";
|
|
57
|
+
readonly value: "wild.richtext.list.number";
|
|
58
|
+
readonly icon: react22.ForwardRefExoticComponent<Omit<react22.SVGProps<SVGSVGElement>, "ref"> & react22.RefAttributes<SVGSVGElement>>;
|
|
59
|
+
}];
|
|
60
|
+
/** @public */
|
|
61
|
+
declare function createSpans(): readonly [{
|
|
62
|
+
type: "object";
|
|
63
|
+
name?: "wild.richtext.span.icon" | undefined;
|
|
64
|
+
} & Omit<sanity36.ArrayOfEntry<sanity36.ObjectDefinition>, "preview"> & {
|
|
65
|
+
preview?: sanity36.PreviewConfig<{
|
|
66
|
+
icon: string;
|
|
67
|
+
}, Record<"icon", any>> | undefined;
|
|
68
|
+
} & sanity36.WidenValidation & sanity36.WidenInitialValue, {
|
|
69
|
+
type: "object";
|
|
70
|
+
name?: "wild.richtext.span.media" | undefined;
|
|
71
|
+
} & Omit<sanity36.ArrayOfEntry<sanity36.ObjectDefinition>, "preview"> & {
|
|
72
|
+
preview?: sanity36.PreviewConfig<{
|
|
73
|
+
type: string;
|
|
74
|
+
}, Record<"type", any>> | undefined;
|
|
75
|
+
} & sanity36.WidenValidation & sanity36.WidenInitialValue];
|
|
76
|
+
/** @public */
|
|
77
|
+
declare function createStyles(): readonly [{
|
|
78
|
+
readonly title: "Heading 2";
|
|
79
|
+
readonly value: "wild.richtext.style.h2";
|
|
80
|
+
readonly component: ({
|
|
81
|
+
children
|
|
82
|
+
}: BlockStyleProps) => react22.JSX.Element;
|
|
83
|
+
}, {
|
|
84
|
+
readonly title: "Heading 3";
|
|
85
|
+
readonly value: "wild.richtext.style.h3";
|
|
86
|
+
readonly component: ({
|
|
87
|
+
children
|
|
88
|
+
}: BlockStyleProps) => react22.JSX.Element;
|
|
89
|
+
}, {
|
|
90
|
+
readonly title: "Heading 4";
|
|
91
|
+
readonly value: "wild.richtext.style.h4";
|
|
92
|
+
readonly component: ({
|
|
93
|
+
children
|
|
94
|
+
}: BlockStyleProps) => react22.JSX.Element;
|
|
95
|
+
}];
|
|
96
|
+
export { createAnnotations as a, createDecorators as i, createSpans as n, createLists as r, createStyles as t };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as sanity46 from "sanity";
|
|
2
|
+
import * as react25 from "react";
|
|
3
|
+
/** @public */
|
|
4
|
+
declare function createAnnotations(): readonly [{
|
|
5
|
+
type: "wild.link";
|
|
6
|
+
name: "wild.richtext.annotation.link";
|
|
7
|
+
} & sanity46.TypeAliasDefinition<"wild.link", "string" | "number" | "boolean" | "object" | "wild.richtext" | "wild.media" | "array" | "block" | "date" | "datetime" | "document" | "file" | "geopoint" | "image" | "reference" | "crossDatasetReference" | "globalDocumentReference" | "slug" | "text" | "url" | "email" | undefined> & {
|
|
8
|
+
preview?: sanity46.PreviewConfig<Record<string, string>, Record<never, any>> | undefined;
|
|
9
|
+
} & sanity46.FieldDefinitionBase & sanity46.WidenValidation & sanity46.WidenInitialValue, {
|
|
10
|
+
type: "object";
|
|
11
|
+
name: "wild.richtext.annotation.textColor";
|
|
12
|
+
} & Omit<sanity46.ObjectDefinition, "preview"> & {
|
|
13
|
+
preview?: sanity46.PreviewConfig<Record<string, string>, Record<never, any>> | undefined;
|
|
14
|
+
} & sanity46.FieldDefinitionBase & sanity46.WidenValidation & sanity46.WidenInitialValue, {
|
|
15
|
+
type: "object";
|
|
16
|
+
name: "wild.richtext.annotation.highlightColor";
|
|
17
|
+
} & Omit<sanity46.ObjectDefinition, "preview"> & {
|
|
18
|
+
preview?: sanity46.PreviewConfig<Record<string, string>, Record<never, any>> | undefined;
|
|
19
|
+
} & sanity46.FieldDefinitionBase & sanity46.WidenValidation & sanity46.WidenInitialValue];
|
|
20
|
+
/** @public */
|
|
21
|
+
declare function createDecorators(): readonly [{
|
|
22
|
+
readonly title: "Strong";
|
|
23
|
+
readonly value: "wild.richtext.decorator.strong";
|
|
24
|
+
readonly icon: react25.ForwardRefExoticComponent<Omit<react25.SVGProps<SVGSVGElement>, "ref"> & react25.RefAttributes<SVGSVGElement>>;
|
|
25
|
+
readonly component: ({
|
|
26
|
+
children
|
|
27
|
+
}: BlockDecoratorProps) => react25.JSX.Element;
|
|
28
|
+
}, {
|
|
29
|
+
readonly title: "Emphasis";
|
|
30
|
+
readonly value: "wild.richtext.decorator.em";
|
|
31
|
+
readonly icon: react25.ForwardRefExoticComponent<Omit<react25.SVGProps<SVGSVGElement>, "ref"> & react25.RefAttributes<SVGSVGElement>>;
|
|
32
|
+
readonly component: ({
|
|
33
|
+
children
|
|
34
|
+
}: BlockDecoratorProps) => react25.JSX.Element;
|
|
35
|
+
}, {
|
|
36
|
+
readonly title: "Code";
|
|
37
|
+
readonly value: "wild.richtext.decorator.code";
|
|
38
|
+
readonly icon: react25.ForwardRefExoticComponent<Omit<react25.SVGProps<SVGSVGElement>, "ref"> & react25.RefAttributes<SVGSVGElement>>;
|
|
39
|
+
readonly component: ({
|
|
40
|
+
children
|
|
41
|
+
}: BlockDecoratorProps) => react25.JSX.Element;
|
|
42
|
+
}, {
|
|
43
|
+
readonly title: "Sup";
|
|
44
|
+
readonly value: "wild.richtext.decorator.sup";
|
|
45
|
+
readonly icon: () => react25.JSX.Element;
|
|
46
|
+
readonly component: ({
|
|
47
|
+
children
|
|
48
|
+
}: BlockDecoratorProps) => react25.JSX.Element;
|
|
49
|
+
}];
|
|
50
|
+
/** @public */
|
|
51
|
+
declare function createLists(): readonly [{
|
|
52
|
+
readonly title: "Bullet";
|
|
53
|
+
readonly value: "wild.richtext.list.bullet";
|
|
54
|
+
readonly icon: react25.ForwardRefExoticComponent<Omit<react25.SVGProps<SVGSVGElement>, "ref"> & react25.RefAttributes<SVGSVGElement>>;
|
|
55
|
+
}, {
|
|
56
|
+
readonly title: "Number";
|
|
57
|
+
readonly value: "wild.richtext.list.number";
|
|
58
|
+
readonly icon: react25.ForwardRefExoticComponent<Omit<react25.SVGProps<SVGSVGElement>, "ref"> & react25.RefAttributes<SVGSVGElement>>;
|
|
59
|
+
}];
|
|
60
|
+
/** @public */
|
|
61
|
+
declare function createSpans(): readonly [{
|
|
62
|
+
type: "object";
|
|
63
|
+
name?: "wild.richtext.span.icon" | undefined;
|
|
64
|
+
} & Omit<sanity46.ArrayOfEntry<sanity46.ObjectDefinition>, "preview"> & {
|
|
65
|
+
preview?: sanity46.PreviewConfig<{
|
|
66
|
+
icon: string;
|
|
67
|
+
}, Record<"icon", any>> | undefined;
|
|
68
|
+
} & sanity46.WidenValidation & sanity46.WidenInitialValue, {
|
|
69
|
+
type: "object";
|
|
70
|
+
name?: "wild.richtext.span.media" | undefined;
|
|
71
|
+
} & Omit<sanity46.ArrayOfEntry<sanity46.ObjectDefinition>, "preview"> & {
|
|
72
|
+
preview?: sanity46.PreviewConfig<{
|
|
73
|
+
type: string;
|
|
74
|
+
}, Record<"type", any>> | undefined;
|
|
75
|
+
} & sanity46.WidenValidation & sanity46.WidenInitialValue];
|
|
76
|
+
/** @public */
|
|
77
|
+
declare function createStyles(): readonly [{
|
|
78
|
+
readonly title: "Heading 2";
|
|
79
|
+
readonly value: "wild.richtext.style.h2";
|
|
80
|
+
readonly component: ({
|
|
81
|
+
children
|
|
82
|
+
}: BlockStyleProps) => react25.JSX.Element;
|
|
83
|
+
}, {
|
|
84
|
+
readonly title: "Heading 3";
|
|
85
|
+
readonly value: "wild.richtext.style.h3";
|
|
86
|
+
readonly component: ({
|
|
87
|
+
children
|
|
88
|
+
}: BlockStyleProps) => react25.JSX.Element;
|
|
89
|
+
}, {
|
|
90
|
+
readonly title: "Heading 4";
|
|
91
|
+
readonly value: "wild.richtext.style.h4";
|
|
92
|
+
readonly component: ({
|
|
93
|
+
children
|
|
94
|
+
}: BlockStyleProps) => react25.JSX.Element;
|
|
95
|
+
}];
|
|
96
|
+
export { createAnnotations as a, createDecorators as i, createSpans as n, createLists as r, createStyles as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../src/types.tsx"],"sourcesContent":["import type {\n ArrayDefinition,\n ArrayOfType,\n ArrayOptions,\n BlockDecoratorDefinition,\n BlockListDefinition,\n BlockStyleDefinition,\n} from \"sanity\";\n\n/** @public */\nconst typeName = \"wild.richtext\" as const;\n\ntype RichtextConfig = {\n /**\n * Custom block types to include in the richtext field.\n */\n blocks?: ArrayOfType<\"object\">[];\n /**\n * Custom inline object types to include in the richtext field.\n */\n spans?: ArrayOfType<\"object\">[];\n /**\n * Custom styles to include in the richtext field.\n */\n styles?: BlockStyleDefinition[];\n /**\n * Custom lists to include in the richtext field.\n */\n lists?: BlockListDefinition[];\n /**\n * Custom annotations to include in the richtext field.\n */\n annotations?: ArrayOfType<\"object\">[];\n /**\n * Custom decorators to include in the richtext field.\n */\n decorators?: BlockDecoratorDefinition[];\n};\n\n/** @public */\ntype PluginConfig = RichtextConfig & {\n /**\n * Whether spell checking should be enabled in the richtext editor.\n */\n spellCheck?: boolean;\n};\n\ntype Size = \"sm\" | \"lg\";\ntype Kind = \"blocks\" | \"spans\" | \"lists\" | \"styles\" | \"decorators\" | \"annotations\";\n\n// Presets are collections of commonly used field options.\n// They allow to quickly set up the richtext field with a predefined set of options.\n// Users can still override individual options when using a preset.\ntype Preset = \"basic\" | \"full\";\ntype Presets = Record<Preset, Omit<FieldOptions, keyof ArrayOptions | \"preset\">>;\n\n// The user can provide custom dimensions as a string.\n// Or use an existing preset size.\ntype MaybeSize = Size | (string & {});\n\n/** @public */\ntype FieldOptions = ArrayOptions & {\n /**\n * Size of the editor field.\n * This will affect the height of the editor in the Sanity studio.\n */\n size?: MaybeSize;\n /**\n * Preset configuration for the richtext field.\n * Presets are predefined sets of options that can be applied to the field.\n */\n preset?: keyof Presets;\n /**\n * Whether the portable text component is active immediately on page load.\n */\n initiallyActive?: boolean;\n /**\n * Whitelist individual parts by their name.\n * To whitelist a complete set of parts, use the `allowedKinds` property.\n */\n allowedParts?: string[];\n /**\n * Blacklist individual parts by their name.\n * To blacklist a complete set of parts, use the `disallowedKinds` property.\n */\n disallowedParts?: string[];\n /**\n * Whitelist kinds of parts by their name.\n * To whitelist individual parts within kinds, use the `allowedParts` property.\n */\n allowedKinds?: Kind[];\n /**\n * Blacklist kinds of parts by their name.\n * To blacklist individual parts within kinds, use the `disallowedParts` property.\n */\n disallowedKinds?: Kind[];\n};\n\nexport { typeName, type RichtextConfig, type PluginConfig, type Size, type Kind, type Presets, type FieldOptions };\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<ArrayDefinition, \"type\" | \"of\" | \"options\"> & {\n type: typeof typeName;\n options?: FieldOptions;\n };\n }\n}\n"],"names":["typeName"],"mappings":"AAUA,MAAMA,WAAW;"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { defineArrayMember } from "sanity";
|
|
3
|
+
function createBlock(block) {
|
|
4
|
+
const blockPreview = {
|
|
5
|
+
select: {
|
|
6
|
+
...block.preview?.select
|
|
7
|
+
},
|
|
8
|
+
prepare: ({
|
|
9
|
+
customTitle,
|
|
10
|
+
...rest
|
|
11
|
+
}) => {
|
|
12
|
+
const defaultPreview = block.preview?.prepare?.(rest) ?? {};
|
|
13
|
+
return {
|
|
14
|
+
title: block.title ?? "Untitled",
|
|
15
|
+
media: block.icon ?? /* @__PURE__ */ jsx(Fragment, { children: "\u2753" }),
|
|
16
|
+
...defaultPreview
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
return defineArrayMember({
|
|
21
|
+
...block,
|
|
22
|
+
preview: blockPreview
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function reshapeListKind(entry, findNeedle) {
|
|
26
|
+
const list = entry.type?.options?.list;
|
|
27
|
+
if (!list) return entry;
|
|
28
|
+
const filteredList = list.filter((s) => findNeedle(s.value));
|
|
29
|
+
return {
|
|
30
|
+
...entry,
|
|
31
|
+
type: {
|
|
32
|
+
...entry.type,
|
|
33
|
+
options: {
|
|
34
|
+
...entry.type.options,
|
|
35
|
+
list: filteredList
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function reshapeOfKind(entry, findNeedle) {
|
|
41
|
+
const list = entry.type?.of;
|
|
42
|
+
if (!list) return entry;
|
|
43
|
+
const filteredOf = list.filter((a) => findNeedle(a.name));
|
|
44
|
+
return {
|
|
45
|
+
...entry,
|
|
46
|
+
type: {
|
|
47
|
+
...entry.type,
|
|
48
|
+
of: filteredOf
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function uniqBy(items, key) {
|
|
53
|
+
const seen = /* @__PURE__ */ new Set(), out = [];
|
|
54
|
+
for (const item of items) {
|
|
55
|
+
const k = key(item);
|
|
56
|
+
seen.has(k) || (seen.add(k), out.push(item));
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
function createAllowFilter({
|
|
61
|
+
label,
|
|
62
|
+
allowed,
|
|
63
|
+
disallowed,
|
|
64
|
+
defaultBehavior = "disallow"
|
|
65
|
+
}) {
|
|
66
|
+
const hasAllowed = allowed !== void 0, hasDisallowed = disallowed !== void 0;
|
|
67
|
+
hasAllowed && hasDisallowed && console.warn(`Wild Sanity Rich Text Field: Both \`allowed${label}\` and \`disallowed${label}\` are set. \`allowed${label}\` will take precedence.`);
|
|
68
|
+
const allowedSet = hasAllowed ? new Set(allowed) : null, disallowedSet = !allowedSet && hasDisallowed ? new Set(disallowed) : null;
|
|
69
|
+
return {
|
|
70
|
+
isAllowed(value) {
|
|
71
|
+
return allowedSet ? allowedSet.has(value) : disallowedSet ? !disallowedSet.has(value) : defaultBehavior === "allow";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const sizeToHeightMap = {
|
|
76
|
+
sm: "10rem",
|
|
77
|
+
lg: "50vh"
|
|
78
|
+
};
|
|
79
|
+
function getHeight(size) {
|
|
80
|
+
return size in sizeToHeightMap ? sizeToHeightMap[size] : size;
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
createAllowFilter,
|
|
84
|
+
createBlock,
|
|
85
|
+
getHeight,
|
|
86
|
+
reshapeListKind,
|
|
87
|
+
reshapeOfKind,
|
|
88
|
+
uniqBy
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../src/internal-utils.tsx"],"sourcesContent":["import { type ArraySchemaType, defineArrayMember, type ObjectDefinition, type ObjectField } from \"sanity\";\nimport type { Size } from \"./types\";\n\n/**\n * Creates a schema definition for a new richtext block.\n * @public\n */\nfunction createBlock(block: ObjectDefinition) {\n const blockPreview = {\n select: {\n ...block.preview?.select,\n },\n prepare: ({ customTitle, ...rest }: Record<string, string>) => {\n const defaultPreview = block.preview?.prepare?.(rest) ?? {};\n\n return {\n title: block.title ?? \"Untitled\",\n media: block.icon ?? <>❓</>,\n ...defaultPreview,\n };\n },\n };\n\n return defineArrayMember({\n ...block,\n preview: blockPreview,\n });\n}\n\n/**\n * Reshapes the list kind of an array field.\n */\nfunction reshapeListKind<E extends ObjectField<ArraySchemaType>>(entry: E, findNeedle: (needle: string) => boolean) {\n const list = entry.type?.options?.list;\n if (!list) return entry;\n const filteredList = list.filter((s) => findNeedle((s as { value: string }).value));\n return { ...entry, type: { ...entry.type, options: { ...entry.type.options, list: filteredList } } };\n}\n\n/**\n * Reshapes the of kind of an array field.\n */\nfunction reshapeOfKind<E extends ObjectField<ArraySchemaType>>(entry: E, findNeedle: (needle: string) => boolean) {\n const list = entry.type?.of;\n if (!list) return entry;\n const filteredOf = list.filter((a: { name: string }) => findNeedle(a.name));\n return { ...entry, type: { ...entry.type, of: filteredOf } };\n}\n\n/**\n * Removes duplicates from an array based on a key function.\n */\nfunction uniqBy<T>(items: T[], key: (t: T) => string): T[] {\n const seen = new Set<string>();\n const out: T[] = [];\n for (const item of items) {\n const k = key(item);\n if (seen.has(k)) continue;\n seen.add(k);\n out.push(item);\n }\n return out;\n}\n\n/**\n * Creates a filter function that allows or disallows values based on a list of allowed or disallowed values.\n */\nfunction createAllowFilter<T extends string>({\n label,\n allowed,\n disallowed,\n defaultBehavior = \"disallow\",\n}: {\n label: string;\n allowed?: readonly T[];\n disallowed?: readonly T[];\n defaultBehavior?: \"allow\" | \"disallow\";\n}) {\n const hasAllowed = allowed !== undefined;\n const hasDisallowed = disallowed !== undefined;\n\n if (hasAllowed && hasDisallowed) {\n console.warn(\n `Wild Sanity Rich Text Field: Both \\`allowed${label}\\` and \\`disallowed${label}\\` are set. \\`allowed${label}\\` will take precedence.`\n );\n }\n\n const allowedSet = hasAllowed ? new Set(allowed) : null;\n const disallowedSet = !allowedSet && hasDisallowed ? new Set(disallowed) : null;\n\n return {\n isAllowed(value: T) {\n if (allowedSet) return allowedSet.has(value);\n if (disallowedSet) return !disallowedSet.has(value);\n return defaultBehavior === \"allow\";\n },\n };\n}\n\nconst sizeToHeightMap = {\n sm: \"10rem\",\n lg: \"50vh\",\n} as const satisfies Record<Size, string>;\n\n/**\n * Retrieves the height value for a given size.\n * If the value is not part of the predefined sizes, assume\n * its a raw size string (e.g., \"200px\") and use it as is.\n */\nfunction getHeight(size: string) {\n return size in sizeToHeightMap ? sizeToHeightMap[size as keyof typeof sizeToHeightMap] : size;\n}\n\nexport { createBlock, createAllowFilter, uniqBy, reshapeListKind, reshapeOfKind, getHeight };\n"],"names":["createBlock","block","blockPreview","select","preview","prepare","customTitle","rest","defaultPreview","title","media","icon","defineArrayMember","reshapeListKind","entry","findNeedle","list","type","options","filteredList","filter","s","value","reshapeOfKind","of","filteredOf","a","name","uniqBy","items","key","seen","Set","out","item","k","has","add","push","createAllowFilter","label","allowed","disallowed","defaultBehavior","hasAllowed","undefined","hasDisallowed","console","warn","allowedSet","disallowedSet","isAllowed","sizeToHeightMap","sm","lg","getHeight","size"],"mappings":";;AAOA,SAASA,YAAYC,OAAyB;AAC5C,QAAMC,eAAe;AAAA,IACnBC,QAAQ;AAAA,MACN,GAAGF,MAAMG,SAASD;AAAAA,IAAAA;AAAAA,IAEpBE,SAASA,CAAC;AAAA,MAAEC;AAAAA,MAAa,GAAGC;AAAAA,IAAAA,MAAmC;AAC7D,YAAMC,iBAAiBP,MAAMG,SAASC,UAAUE,IAAI,KAAK,CAAA;AAEzD,aAAO;AAAA,QACLE,OAAOR,MAAMQ,SAAS;AAAA,QACtBC,OAAOT,MAAMU,QAAQ,oBAAA,UAAA,EAAE,UAAA,UAAC;AAAA,QACxB,GAAGH;AAAAA,MAAAA;AAAAA,IAEP;AAAA,EAAA;AAGF,SAAOI,kBAAkB;AAAA,IACvB,GAAGX;AAAAA,IACHG,SAASF;AAAAA,EAAAA,CACV;AACH;AAKA,SAASW,gBAAwDC,OAAUC,YAAyC;AAClH,QAAMC,OAAOF,MAAMG,MAAMC,SAASF;AAClC,MAAI,CAACA,KAAM,QAAOF;AAClB,QAAMK,eAAeH,KAAKI,OAAQC,OAAMN,WAAYM,EAAwBC,KAAK,CAAC;AAClF,SAAO;AAAA,IAAE,GAAGR;AAAAA,IAAOG,MAAM;AAAA,MAAE,GAAGH,MAAMG;AAAAA,MAAMC,SAAS;AAAA,QAAE,GAAGJ,MAAMG,KAAKC;AAAAA,QAASF,MAAMG;AAAAA,MAAAA;AAAAA,IAAa;AAAA,EAAE;AACnG;AAKA,SAASI,cAAsDT,OAAUC,YAAyC;AAChH,QAAMC,OAAOF,MAAMG,MAAMO;AACzB,MAAI,CAACR,KAAM,QAAOF;AAClB,QAAMW,aAAaT,KAAKI,OAAQM,OAAwBX,WAAWW,EAAEC,IAAI,CAAC;AAC1E,SAAO;AAAA,IAAE,GAAGb;AAAAA,IAAOG,MAAM;AAAA,MAAE,GAAGH,MAAMG;AAAAA,MAAMO,IAAIC;AAAAA,IAAAA;AAAAA,EAAW;AAC3D;AAKA,SAASG,OAAUC,OAAYC,KAA4B;AACzD,QAAMC,OAAO,oBAAIC,IAAAA,GACXC,MAAW,CAAA;AACjB,aAAWC,QAAQL,OAAO;AACxB,UAAMM,IAAIL,IAAII,IAAI;AACdH,SAAKK,IAAID,CAAC,MACdJ,KAAKM,IAAIF,CAAC,GACVF,IAAIK,KAAKJ,IAAI;AAAA,EACf;AACA,SAAOD;AACT;AAKA,SAASM,kBAAoC;AAAA,EAC3CC;AAAAA,EACAC;AAAAA,EACAC;AAAAA,EACAC,kBAAkB;AAMpB,GAAG;AACD,QAAMC,aAAaH,YAAYI,QACzBC,gBAAgBJ,eAAeG;AAEjCD,gBAAcE,iBAChBC,QAAQC,KACN,8CAA8CR,KAAK,sBAAsBA,KAAK,wBAAwBA,KAAK,0BAC7G;AAGF,QAAMS,aAAaL,aAAa,IAAIZ,IAAIS,OAAO,IAAI,MAC7CS,gBAAgB,CAACD,cAAcH,gBAAgB,IAAId,IAAIU,UAAU,IAAI;AAE3E,SAAO;AAAA,IACLS,UAAU7B,OAAU;AAClB,aAAI2B,aAAmBA,WAAWb,IAAId,KAAK,IACvC4B,gBAAsB,CAACA,cAAcd,IAAId,KAAK,IAC3CqB,oBAAoB;AAAA,IAC7B;AAAA,EAAA;AAEJ;AAEA,MAAMS,kBAAkB;AAAA,EACtBC,IAAI;AAAA,EACJC,IAAI;AACN;AAOA,SAASC,UAAUC,MAAc;AAC/B,SAAOA,QAAQJ,kBAAkBA,gBAAgBI,IAAI,IAAoCA;AAC3F;"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
+
var jsxRuntime = require("react/jsx-runtime"), sanityMediaField = require("@madebywild/sanity-media-field"), sanity = require("sanity"), types = require("../_chunks-cjs/types.cjs");
|
|
4
|
+
function createBlock() {
|
|
5
|
+
return sanity.defineArrayMember({
|
|
6
|
+
name: `${types.typeName}.block.media`,
|
|
7
|
+
type: "object",
|
|
8
|
+
title: "Media Block",
|
|
9
|
+
description: "Embed block video or image content.",
|
|
10
|
+
icon: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u{1F5BC}\uFE0F" }),
|
|
11
|
+
fields: [sanity.defineField({
|
|
12
|
+
name: "appMedia",
|
|
13
|
+
type: "wild.media",
|
|
14
|
+
options: {
|
|
15
|
+
collapsed: !1,
|
|
16
|
+
collapsible: !1,
|
|
17
|
+
inline: !0,
|
|
18
|
+
extensions: [{
|
|
19
|
+
caption: {
|
|
20
|
+
enabled: !0
|
|
21
|
+
}
|
|
22
|
+
}, {
|
|
23
|
+
videoOptions: {
|
|
24
|
+
enabled: !0
|
|
25
|
+
}
|
|
26
|
+
}, {
|
|
27
|
+
customRatio: {
|
|
28
|
+
enabled: !0
|
|
29
|
+
}
|
|
30
|
+
}]
|
|
31
|
+
}
|
|
32
|
+
})],
|
|
33
|
+
preview: {
|
|
34
|
+
select: sanityMediaField.selectMediaPreview("appMedia"),
|
|
35
|
+
prepare: (props) => sanityMediaField.prepareMediaPreview(props)
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
exports.createBlock = createBlock;
|
|
40
|
+
//# sourceMappingURL=media-block.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-block.cjs","sources":["../../src/blocks/media-block.tsx"],"sourcesContent":["import { prepareMediaPreview, selectMediaPreview } from \"@madebywild/sanity-media-field\";\nimport { defineArrayMember, defineField } from \"sanity\";\nimport { typeName } from \"../types\";\n\n/** @public */\nfunction createBlock() {\n return defineArrayMember({\n name: `${typeName}.block.media`,\n type: \"object\",\n title: \"Media Block\",\n description: \"Embed block video or image content.\",\n icon: () => <>🖼️</>,\n fields: [\n defineField({\n name: \"appMedia\",\n type: \"wild.media\",\n options: {\n collapsed: false,\n collapsible: false,\n inline: true,\n extensions: [{ caption: { enabled: true } }, { videoOptions: { enabled: true } }, { customRatio: { enabled: true } }],\n },\n }),\n ],\n preview: {\n select: selectMediaPreview(\"appMedia\"),\n prepare: (props) => prepareMediaPreview(props),\n },\n });\n}\n\nexport { createBlock };\n"],"names":["createBlock","defineArrayMember","name","typeName","type","title","description","icon","jsx","Fragment","fields","defineField","options","collapsed","collapsible","inline","extensions","caption","enabled","videoOptions","customRatio","preview","select","selectMediaPreview","prepare","props","prepareMediaPreview"],"mappings":";;;AAKA,SAASA,cAAc;AACrB,SAAOC,yBAAkB;AAAA,IACvBC,MAAM,GAAGC,MAAAA,QAAQ;AAAA,IACjBC,MAAM;AAAA,IACNC,OAAO;AAAA,IACPC,aAAa;AAAA,IACbC,MAAMA,MAAMC,2BAAAA,IAAAC,WAAAA,UAAA,EAAE,UAAA,kBAAA,CAAG;AAAA,IACjBC,QAAQ,CACNC,OAAAA,YAAY;AAAA,MACVT,MAAM;AAAA,MACNE,MAAM;AAAA,MACNQ,SAAS;AAAA,QACPC,WAAW;AAAA,QACXC,aAAa;AAAA,QACbC,QAAQ;AAAA,QACRC,YAAY,CAAC;AAAA,UAAEC,SAAS;AAAA,YAAEC,SAAS;AAAA,UAAA;AAAA,QAAK,GAAK;AAAA,UAAEC,cAAc;AAAA,YAAED,SAAS;AAAA,UAAA;AAAA,QAAK,GAAK;AAAA,UAAEE,aAAa;AAAA,YAAEF,SAAS;AAAA,UAAA;AAAA,QAAK,CAAG;AAAA,MAAA;AAAA,IACtH,CACD,CAAC;AAAA,IAEJG,SAAS;AAAA,MACPC,QAAQC,iBAAAA,mBAAmB,UAAU;AAAA,MACrCC,SAAUC,CAAAA,UAAUC,iBAAAA,oBAAoBD,KAAK;AAAA,IAAA;AAAA,EAC/C,CACD;AACH;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as sanity31 from "sanity";
|
|
2
|
+
/** @public */
|
|
3
|
+
declare function createBlock(): {
|
|
4
|
+
type: "object";
|
|
5
|
+
name?: "wild.richtext.block.media" | undefined;
|
|
6
|
+
} & Omit<sanity31.ArrayOfEntry<sanity31.ObjectDefinition>, "preview"> & {
|
|
7
|
+
preview?: sanity31.PreviewConfig<{
|
|
8
|
+
readonly kind: string;
|
|
9
|
+
readonly videoKind: string;
|
|
10
|
+
readonly motionKind: string;
|
|
11
|
+
readonly image: string;
|
|
12
|
+
readonly videoCover: string;
|
|
13
|
+
readonly videoFile: string;
|
|
14
|
+
readonly vimeoUrl: string;
|
|
15
|
+
readonly youtubeUrl: string;
|
|
16
|
+
readonly muxPlaybackId: string;
|
|
17
|
+
}, Record<"image" | "kind" | "videoKind" | "motionKind" | "videoCover" | "videoFile" | "vimeoUrl" | "youtubeUrl" | "muxPlaybackId", any>> | undefined;
|
|
18
|
+
} & sanity31.WidenValidation & sanity31.WidenInitialValue;
|
|
19
|
+
export { createBlock };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as sanity31 from "sanity";
|
|
2
|
+
/** @public */
|
|
3
|
+
declare function createBlock(): {
|
|
4
|
+
type: "object";
|
|
5
|
+
name?: "wild.richtext.block.media" | undefined;
|
|
6
|
+
} & Omit<sanity31.ArrayOfEntry<sanity31.ObjectDefinition>, "preview"> & {
|
|
7
|
+
preview?: sanity31.PreviewConfig<{
|
|
8
|
+
readonly kind: string;
|
|
9
|
+
readonly videoKind: string;
|
|
10
|
+
readonly motionKind: string;
|
|
11
|
+
readonly image: string;
|
|
12
|
+
readonly videoCover: string;
|
|
13
|
+
readonly videoFile: string;
|
|
14
|
+
readonly vimeoUrl: string;
|
|
15
|
+
readonly youtubeUrl: string;
|
|
16
|
+
readonly muxPlaybackId: string;
|
|
17
|
+
}, Record<"image" | "kind" | "videoKind" | "motionKind" | "videoCover" | "videoFile" | "vimeoUrl" | "youtubeUrl" | "muxPlaybackId", any>> | undefined;
|
|
18
|
+
} & sanity31.WidenValidation & sanity31.WidenInitialValue;
|
|
19
|
+
export { createBlock };
|