sanity-plugin-markdown 3.0.1 → 4.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Sanity.io
3
+ Copyright (c) 2023 Sanity.io
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -7,26 +7,20 @@
7
7
 
8
8
  A Markdown editor with preview for Sanity Studio.
9
9
 
10
- Supports Github flavored markdown and image uploads. You can either drag image(s) into the editor or click the bottom bar to bring up a file selector.
10
+ Supports Github flavored markdown and image uploads.
11
+ You can either drag image(s) into the editor or click the bottom bar to bring up a file selector.
11
12
  The resulting image URL(s) are inserted with a default width parameter which you can change to your liking using the [Sanity image pipeline parameters](https://www.sanity.io/docs/image-urls).
12
-
13
- ### Known issues with the current v3 version
14
13
 
15
- The v2 version used react-mde for editing. The current v3 version @uiw/react-md-editor. This may change before GA.
14
+ The current version is a wrapper around [React SimpleMDE (EasyMDE) Markdown Editor](https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor),
15
+ and by extension, [EasyMDE](https://github.com/Ionaru/easy-markdown-editor).
16
16
 
17
- At the moment the v3 version does not have drag-and-drop image upload support.
18
- You can still add markdown image tags, but you will have to get the image url yourself for now.
17
+ ![example.png](./assets/example.png)
19
18
 
20
19
  ## Installation
20
+ Install `sanity-plugin-markdown` and `easymde@2` (peer dependency).
21
21
 
22
22
  ```
23
- npm install --save sanity-plugin-markdown
24
- ```
25
-
26
- or
27
-
28
- ```
29
- yarn add sanity-plugin-markdown
23
+ npm install --save sanity-plugin-markdown easymde@2
30
24
  ```
31
25
 
32
26
  ## Usage
@@ -59,10 +53,139 @@ const myDocument = {
59
53
  ]
60
54
  }
61
55
  ```
62
- ### Demo
56
+ ### Next.js compatability
57
+ Next.js *without* Next 13 app directory does not support css imports from `node_modules`.
58
+
59
+ To use this plugin in this context (`pages` directory), use the `sanity-plugin-markdown/next` import instead of `sanity-plugin-markdown`:
60
+ ```js
61
+ import { markdownSchema } from "sanity-plugin-markdown/next";
62
+ ```
63
+
64
+ Then, make sure to add
65
+ ```js
66
+ import 'easymde/dist/easymde.min.css'
67
+ ```
68
+
69
+ to the top of `pages/_app.tsx`.
70
+
71
+ ### Customizing the default markdown input editor
72
+
73
+ The plugin takes an `input` config option that can be used in combination with the `MarkdownInput` export
74
+ to configure the underlying React SimpleMDE component:
75
+
76
+ * Create a custom component that wraps MarkdownInput
77
+ * Memoize reactMdeProps and pass along
78
+
79
+ ```tsx
80
+ // CustomMarkdownInput.tsx
81
+ import { MarkdownInput, MarkdownInputProps } from 'sanity-plugin-markdown'
82
+
83
+ export function CustomMarkdownInput(props) {
84
+ const reactMdeProps: MarkdownInputProps['reactMdeProps'] =
85
+ useMemo(() => {
86
+ return {
87
+ options: {
88
+ toolbar: ['bold', 'italic'],
89
+ // more options available, see:
90
+ // https://github.com/Ionaru/easy-markdown-editor#options-list
91
+ },
92
+ // more props available, see:
93
+ // https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor
94
+ }
95
+ }, [])
96
+
97
+ return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />
98
+ }
99
+ ```
100
+ Set the plugin input option:
101
+
102
+ ```ts
103
+ // studio.config.ts
104
+ import {markdownSchema} from 'sanity-plugin-markdown'
105
+ import {CustomMarkdownInput} from './CustomMarkdownInput'
106
+
107
+ export default defineConfig({
108
+ // ... rest of the config
109
+ plugins: [
110
+ markdownSchema({input: CustomMarkdownInput}),
111
+ ]
112
+ })
113
+ ```
114
+
115
+ ### Customize editor for a single field
116
+
117
+ Implement a custom input similar to the one above, and use it as `components.input` on the field directly.
118
+
119
+ ```ts
120
+ defineField({
121
+ type: 'markdown',
122
+ name: 'markdown',
123
+ title: 'Markdown',
124
+ components: {input: CustomMarkdownInput}
125
+ })
126
+ ```
127
+
128
+ ### Customizing editor preview
129
+
130
+ One way to customize the preview that does not involve ReactDOMServer
131
+ (used by React SimpleMDE) is to install [marked](https://github.com/markedjs/marked) and
132
+ [DOMPurify](https://github.com/cure53/DOMPurify) and create a custom preview:
133
+
134
+ `npm i marked dompurify`
135
+
136
+ Then use these to create a custom editor:
137
+
138
+ ```tsx
139
+ // MarkdownInputCustomPreview.tsx
140
+ import { MarkdownInput, MarkdownInputProps } from 'sanity-plugin-markdown'
141
+ import DOMPurify from 'dompurify'
142
+ import {marked} from 'marked'
143
+
144
+ export function CustomMarkdownInput(props) {
145
+ const reactMdeProps: MarkdownInputProps['reactMdeProps'] =
146
+ useMemo(() => {
147
+ return {
148
+ options: {
149
+ previewRender: (markdownText) => {
150
+ // configure as needed according to
151
+ // https://github.com/markedjs/marked#docs
152
+ return DOMPurify.sanitize(marked.parse(markdownText))
153
+ }
154
+ //customizing using renderingConfig is also an option
155
+ },
156
+ }
157
+ }, [])
158
+
159
+ return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />
160
+ }
161
+ ```
162
+
163
+ Use the component as described in previous sections.
164
+
165
+ ### Custom image urls
63
166
 
64
- ![demo](https://user-images.githubusercontent.com/38528/113196621-91ec8780-9218-11eb-86cc-cf0adfa2fd01.gif)
167
+ Provide a function to options.imageUrl that takes a SanityImageAssetDocument and returns a string.
65
168
 
169
+ The function will be invoked whenever an image is pasted or dragged into the markdown editor,
170
+ after upload completes.
171
+
172
+ The default implementation uses
173
+ ```js
174
+ imageAsset => `${imageAsset.url}?w=450`
175
+ ```
176
+
177
+ #### Example imageUrl option
178
+
179
+ ```js
180
+ defineField({
181
+ type: 'markdown',
182
+ name: 'markdown',
183
+ title: 'Markdown',
184
+ options: {
185
+ imageUrl: imageAsset => `${imageAsset.url}?w=400&h=400`
186
+ }
187
+ })
188
+ ```
66
189
 
67
190
  ## License
68
191
 
@@ -0,0 +1,162 @@
1
+ 'use strict';
2
+
3
+ var _templateObject;
4
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
5
+ var sanity = require('sanity');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var react = require('react');
8
+ var styled = require('styled-components');
9
+ var ui = require('@sanity/ui');
10
+ function _interopDefaultCompat(e) {
11
+ return e && typeof e === 'object' && 'default' in e ? e : {
12
+ default: e
13
+ };
14
+ }
15
+ var styled__default = /*#__PURE__*/_interopDefaultCompat(styled);
16
+ const MarkdownInputStyles = styled__default.default(ui.Box)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n & .CodeMirror.CodeMirror {\n color: ", ";\n border-color: ", ";\n background-color: inherit;\n }\n\n & .cm-s-easymde .CodeMirror-cursor {\n border-color: ", ";\n }\n\n & .editor-toolbar,\n .editor-preview-side {\n border-color: ", ";\n }\n\n & .CodeMirror-focused .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ", ";\n }\n\n & .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ", ";\n }\n\n & .editor-toolbar > * {\n color: ", ";\n }\n\n & .editor-toolbar > .active,\n .editor-toolbar > button:hover,\n .editor-preview pre,\n .cm-s-easymde .cm-comment {\n background-color: ", ";\n }\n\n & .editor-preview {\n background-color: ", ";\n\n & h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: revert;\n }\n\n & ul,\n li {\n list-style: revert;\n padding: revert;\n }\n\n & a {\n text-decoration: revert;\n }\n }\n"])), _ref => {
17
+ let {
18
+ theme
19
+ } = _ref;
20
+ return theme.sanity.color.card.enabled.fg;
21
+ }, _ref2 => {
22
+ let {
23
+ theme
24
+ } = _ref2;
25
+ return theme.sanity.color.card.enabled.border;
26
+ }, _ref3 => {
27
+ let {
28
+ theme
29
+ } = _ref3;
30
+ return theme.sanity.color.card.enabled.fg;
31
+ }, _ref4 => {
32
+ let {
33
+ theme
34
+ } = _ref4;
35
+ return theme.sanity.color.card.enabled.border;
36
+ }, _ref5 => {
37
+ let {
38
+ theme
39
+ } = _ref5;
40
+ return theme.sanity.color.selectable.primary.hovered.bg;
41
+ }, _ref6 => {
42
+ let {
43
+ theme
44
+ } = _ref6;
45
+ return theme.sanity.color.card.enabled.bg;
46
+ }, _ref7 => {
47
+ let {
48
+ theme
49
+ } = _ref7;
50
+ return theme.sanity.color.card.enabled.fg;
51
+ }, _ref8 => {
52
+ let {
53
+ theme
54
+ } = _ref8;
55
+ return theme.sanity.color.card.enabled.bg;
56
+ }, _ref9 => {
57
+ let {
58
+ theme
59
+ } = _ref9;
60
+ return theme.sanity.color.card.enabled.bg;
61
+ });
62
+ const SimpleMdeReact = react.lazy(() => import('react-simplemde-editor'));
63
+ function useSimpleMdeReact() {
64
+ const [mounted, setMounted] = react.useState(false);
65
+ react.useEffect(() => {
66
+ requestAnimationFrame(() => setMounted(true));
67
+ }, []);
68
+ return mounted ? SimpleMdeReact : null;
69
+ }
70
+ const defaultMdeTools = ["heading", "bold", "italic", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "code", "|", "preview", "side-by-side"];
71
+ function MarkdownInput(props) {
72
+ var _a;
73
+ const {
74
+ value = "",
75
+ onChange,
76
+ elementProps: {
77
+ onBlur,
78
+ onFocus,
79
+ ref
80
+ },
81
+ reactMdeProps: {
82
+ options: mdeCustomOptions,
83
+ ...reactMdeProps
84
+ } = {},
85
+ schemaType
86
+ } = props;
87
+ const client = sanity.useClient({
88
+ apiVersion: "2022-01-01"
89
+ });
90
+ const {
91
+ imageUrl
92
+ } = (_a = schemaType.options) != null ? _a : {};
93
+ const imageUpload = react.useCallback((file, onSuccess, onError) => {
94
+ client.assets.upload("image", file).then(doc => onSuccess(imageUrl ? imageUrl(doc) : "".concat(doc.url, "?w=450"))).catch(e => {
95
+ console.error(e);
96
+ onError(e.message);
97
+ });
98
+ }, [client, imageUrl]);
99
+ const mdeOptions = react.useMemo(() => {
100
+ return {
101
+ autofocus: false,
102
+ spellChecker: false,
103
+ sideBySideFullscreen: false,
104
+ uploadImage: true,
105
+ imageUploadFunction: imageUpload,
106
+ toolbar: defaultMdeTools,
107
+ status: false,
108
+ ...mdeCustomOptions
109
+ };
110
+ }, [imageUpload, mdeCustomOptions]);
111
+ const handleChange = react.useCallback(newValue => {
112
+ onChange(sanity.PatchEvent.from(newValue ? sanity.set(newValue) : sanity.unset()));
113
+ }, [onChange]);
114
+ const SimpleMdeReact = useSimpleMdeReact();
115
+ return /* @__PURE__ */jsxRuntime.jsx(MarkdownInputStyles, {
116
+ children: SimpleMdeReact && /* @__PURE__ */jsxRuntime.jsx(react.Suspense, {
117
+ fallback: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
118
+ padding: 3,
119
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
120
+ children: "Loading editor..."
121
+ })
122
+ }),
123
+ children: /* @__PURE__ */jsxRuntime.jsx(SimpleMdeReact, {
124
+ ...reactMdeProps,
125
+ ref,
126
+ value,
127
+ onChange: handleChange,
128
+ onBlur,
129
+ onFocus,
130
+ options: mdeOptions,
131
+ spellCheck: false
132
+ })
133
+ })
134
+ });
135
+ }
136
+ const markdownTypeName = "markdown";
137
+ const markdownSchemaType = sanity.defineType({
138
+ type: "string",
139
+ name: markdownTypeName,
140
+ title: "Markdown",
141
+ components: {
142
+ input: MarkdownInput
143
+ }
144
+ });
145
+ const markdownSchema = sanity.definePlugin(config => {
146
+ return {
147
+ name: "markdown-editor",
148
+ schema: {
149
+ types: [config && config.input ? {
150
+ ...markdownSchemaType,
151
+ components: {
152
+ input: config.input
153
+ }
154
+ } : markdownSchemaType]
155
+ }
156
+ };
157
+ });
158
+ exports.MarkdownInput = MarkdownInput;
159
+ exports.defaultMdeTools = defaultMdeTools;
160
+ exports.markdownSchema = markdownSchema;
161
+ exports.markdownSchemaType = markdownSchemaType;
162
+ //# sourceMappingURL=plugin-b7a179e6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-b7a179e6.js","sources":["../../src/components/MarkdownInputStyles.tsx","../../src/components/useSimpleMdeReact.tsx","../../src/components/MarkdownInput.tsx","../../src/schema.ts","../../src/plugin.tsx"],"sourcesContent":["import styled from 'styled-components'\nimport {Box} from '@sanity/ui'\n\nexport const MarkdownInputStyles = styled(Box)`\n & .CodeMirror.CodeMirror {\n color: ${({theme}) => theme.sanity.color.card.enabled.fg};\n border-color: ${({theme}) => theme.sanity.color.card.enabled.border};\n background-color: inherit;\n }\n\n & .cm-s-easymde .CodeMirror-cursor {\n border-color: ${({theme}) => theme.sanity.color.card.enabled.fg};\n }\n\n & .editor-toolbar,\n .editor-preview-side {\n border-color: ${({theme}) => theme.sanity.color.card.enabled.border};\n }\n\n & .CodeMirror-focused .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ${({theme}) => theme.sanity.color.selectable.primary.hovered.bg};\n }\n\n & .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ${({theme}) => theme.sanity.color.card.enabled.bg};\n }\n\n & .editor-toolbar > * {\n color: ${({theme}) => theme.sanity.color.card.enabled.fg};\n }\n\n & .editor-toolbar > .active,\n .editor-toolbar > button:hover,\n .editor-preview pre,\n .cm-s-easymde .cm-comment {\n background-color: ${({theme}) => theme.sanity.color.card.enabled.bg};\n }\n\n & .editor-preview {\n background-color: ${({theme}) => theme.sanity.color.card.enabled.bg};\n\n & h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: revert;\n }\n\n & ul,\n li {\n list-style: revert;\n padding: revert;\n }\n\n & a {\n text-decoration: revert;\n }\n }\n`\n","import {lazy, useEffect, useState} from 'react'\n\nexport const SimpleMdeReact = lazy(() => import('react-simplemde-editor'))\n\nexport function useSimpleMdeReact() {\n const [mounted, setMounted] = useState(false)\n useEffect(() => {\n requestAnimationFrame(() => setMounted(true))\n }, [])\n\n return mounted ? SimpleMdeReact : null\n}\n","import {type Options as EasyMdeOptions} from 'easymde'\nimport React, {Suspense, useCallback, useMemo} from 'react'\n// dont import non-types here, it will break SSR on next\nimport type {SimpleMDEReactProps} from 'react-simplemde-editor'\nimport {PatchEvent, set, StringInputProps, unset, useClient} from 'sanity'\nimport {MarkdownOptions} from '../schema'\nimport {MarkdownInputStyles} from './MarkdownInputStyles'\nimport {useSimpleMdeReact} from './useSimpleMdeReact'\nimport {Box, Text} from '@sanity/ui'\n\nexport interface MarkdownInputProps extends StringInputProps {\n /**\n * These are passed along directly to\n *\n * Note: MarkdownInput sets certain reactMdeProps.options by default.\n * These will be merged with any custom options.\n * */\n reactMdeProps?: Omit<SimpleMDEReactProps, 'value' | 'onChange'>\n}\n\nexport const defaultMdeTools: EasyMdeOptions['toolbar'] = [\n 'heading',\n 'bold',\n 'italic',\n '|',\n 'quote',\n 'unordered-list',\n 'ordered-list',\n '|',\n 'link',\n 'image',\n 'code',\n '|',\n 'preview',\n 'side-by-side',\n]\n\nexport function MarkdownInput(props: MarkdownInputProps) {\n const {\n value = '',\n onChange,\n elementProps: {onBlur, onFocus, ref},\n reactMdeProps: {options: mdeCustomOptions, ...reactMdeProps} = {},\n schemaType,\n } = props\n const client = useClient({apiVersion: '2022-01-01'})\n const {imageUrl} = (schemaType.options as MarkdownOptions | undefined) ?? {}\n\n const imageUpload = useCallback(\n (file: File, onSuccess: (url: string) => void, onError: (error: string) => void) => {\n client.assets\n .upload('image', file)\n .then((doc) => onSuccess(imageUrl ? imageUrl(doc) : `${doc.url}?w=450`))\n .catch((e) => {\n console.error(e)\n onError(e.message)\n })\n },\n [client, imageUrl]\n )\n\n const mdeOptions: EasyMdeOptions = useMemo(() => {\n return {\n autofocus: false,\n spellChecker: false,\n sideBySideFullscreen: false,\n uploadImage: true,\n imageUploadFunction: imageUpload,\n toolbar: defaultMdeTools,\n status: false,\n ...mdeCustomOptions,\n }\n }, [imageUpload, mdeCustomOptions])\n\n const handleChange = useCallback(\n (newValue: string) => {\n onChange(PatchEvent.from(newValue ? set(newValue) : unset()))\n },\n [onChange]\n )\n\n const SimpleMdeReact = useSimpleMdeReact()\n\n return (\n <MarkdownInputStyles>\n {SimpleMdeReact && (\n <Suspense\n fallback={\n <Box padding={3}>\n <Text>Loading editor...</Text>\n </Box>\n }\n >\n <SimpleMdeReact\n {...reactMdeProps}\n ref={ref}\n value={value}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n options={mdeOptions}\n spellCheck={false}\n />\n </Suspense>\n )}\n </MarkdownInputStyles>\n )\n}\n","import {defineType, StringDefinition} from 'sanity'\nimport {MarkdownInput} from './components/MarkdownInput'\nimport {SanityImageAssetDocument} from '@sanity/client'\n\nexport const markdownTypeName = 'markdown' as const\n\nexport interface MarkdownOptions {\n /**\n * Used to create image url for any uploaded image.\n * The function will be invoked whenever an image is pasted or dragged into the\n * markdown editor, after upload completes.\n *\n * The default implementation uses\n * ```js\n * imageAsset => `${imageAsset.url}?w=450`\n * ```\n * ## Example\n * ```js\n * {\n * imageUrl: imageAsset => `${imageAsset.url}?w=400&h=400`\n * }\n * ```\n * @param imageAsset\n */\n imageUrl?: (imageAsset: SanityImageAssetDocument) => string\n}\n\n/**\n * @public\n */\nexport interface MarkdownDefinition extends Omit<StringDefinition, 'type' | 'fields' | 'options'> {\n type: typeof markdownTypeName\n options?: MarkdownOptions\n}\n\ndeclare module '@sanity/types' {\n // makes type: 'markdown' narrow correctly when using defineType/defineField/defineArrayMember\n export interface IntrinsicDefinitions {\n markdown: MarkdownDefinition\n }\n}\n\nexport const markdownSchemaType = defineType({\n type: 'string',\n name: markdownTypeName,\n title: 'Markdown',\n components: {input: MarkdownInput},\n})\n","import {definePlugin, StringInputProps} from 'sanity'\nimport {markdownSchemaType} from './schema'\nimport {ReactElement} from 'react'\n\nexport interface MarkdownConfig {\n /**\n * When provided, will replace the default input component.\n *\n * Use this to customize MarkdownInput by wrapping it in a custom component,\n * and provide any custom props for https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor\n * via the `reactMdeProps` prop.\n *\n * ### Example\n *\n * ```tsx\n * // CustomMarkdownInput.tsx\n * import { MarkdownInput, MarkdownInputProps } from 'sanity-plugin-markdown'\n *\n * export function CustomMarkdownInput(props) {\n * const reactMdeProps: MarkdownInputProps['reactMdeProps'] =\n * useMemo(() => {\n * return {\n * options: {\n * toolbar: ['bold', 'italic'],\n * // more options available, see:\n * // https://github.com/Ionaru/easy-markdown-editor#options-list\n * },\n * // more props available, see:\n * // https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor\n * }\n * }, [])\n *\n * return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />\n * }\n *\n * // studio.config.ts\n * markdownSchema({input: CustomMarkdownInput})\n * ```\n */\n input?: (props: StringInputProps) => ReactElement\n}\n\nexport const markdownSchema = definePlugin((config: MarkdownConfig | void) => {\n return {\n name: 'markdown-editor',\n schema: {\n types: [\n config && config.input\n ? {...markdownSchemaType, components: {input: config.input}}\n : markdownSchemaType,\n ],\n },\n }\n})\n"],"names":["MarkdownInputStyles","styled","Box","_templateObject","_taggedTemplateLiteral","_ref","theme","sanity","color","card","enabled","fg","_ref2","border","_ref3","_ref4","_ref5","selectable","primary","hovered","bg","_ref6","_ref7","_ref8","_ref9","SimpleMdeReact","lazy","useSimpleMdeReact","mounted","setMounted","useState","useEffect","requestAnimationFrame","defaultMdeTools","MarkdownInput","props","_a","value","onChange","elementProps","onBlur","onFocus","ref","reactMdeProps","options","mdeCustomOptions","schemaType","client","useClient","apiVersion","imageUrl","imageUpload","useCallback","file","onSuccess","onError","assets","upload","then","doc","concat","url","catch","e","console","error","message","mdeOptions","useMemo","autofocus","spellChecker","sideBySideFullscreen","uploadImage","imageUploadFunction","toolbar","status","handleChange","newValue","PatchEvent","from","set","unset","jsx","children","Suspense","fallback","padding","Text","spellCheck","markdownTypeName","markdownSchemaType","defineType","type","name","title","components","input","markdownSchema","definePlugin","config","schema","types"],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ var _templateObject;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { useClient, PatchEvent, set, unset, defineType, definePlugin } from 'sanity';
4
+ import { jsx } from 'react/jsx-runtime';
5
+ import { lazy, useState, useEffect, useCallback, useMemo, Suspense } from 'react';
6
+ import styled from 'styled-components';
7
+ import { Box, Text } from '@sanity/ui';
8
+ const MarkdownInputStyles = styled(Box)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n & .CodeMirror.CodeMirror {\n color: ", ";\n border-color: ", ";\n background-color: inherit;\n }\n\n & .cm-s-easymde .CodeMirror-cursor {\n border-color: ", ";\n }\n\n & .editor-toolbar,\n .editor-preview-side {\n border-color: ", ";\n }\n\n & .CodeMirror-focused .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ", ";\n }\n\n & .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ", ";\n }\n\n & .editor-toolbar > * {\n color: ", ";\n }\n\n & .editor-toolbar > .active,\n .editor-toolbar > button:hover,\n .editor-preview pre,\n .cm-s-easymde .cm-comment {\n background-color: ", ";\n }\n\n & .editor-preview {\n background-color: ", ";\n\n & h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: revert;\n }\n\n & ul,\n li {\n list-style: revert;\n padding: revert;\n }\n\n & a {\n text-decoration: revert;\n }\n }\n"])), _ref => {
9
+ let {
10
+ theme
11
+ } = _ref;
12
+ return theme.sanity.color.card.enabled.fg;
13
+ }, _ref2 => {
14
+ let {
15
+ theme
16
+ } = _ref2;
17
+ return theme.sanity.color.card.enabled.border;
18
+ }, _ref3 => {
19
+ let {
20
+ theme
21
+ } = _ref3;
22
+ return theme.sanity.color.card.enabled.fg;
23
+ }, _ref4 => {
24
+ let {
25
+ theme
26
+ } = _ref4;
27
+ return theme.sanity.color.card.enabled.border;
28
+ }, _ref5 => {
29
+ let {
30
+ theme
31
+ } = _ref5;
32
+ return theme.sanity.color.selectable.primary.hovered.bg;
33
+ }, _ref6 => {
34
+ let {
35
+ theme
36
+ } = _ref6;
37
+ return theme.sanity.color.card.enabled.bg;
38
+ }, _ref7 => {
39
+ let {
40
+ theme
41
+ } = _ref7;
42
+ return theme.sanity.color.card.enabled.fg;
43
+ }, _ref8 => {
44
+ let {
45
+ theme
46
+ } = _ref8;
47
+ return theme.sanity.color.card.enabled.bg;
48
+ }, _ref9 => {
49
+ let {
50
+ theme
51
+ } = _ref9;
52
+ return theme.sanity.color.card.enabled.bg;
53
+ });
54
+ const SimpleMdeReact = lazy(() => import('react-simplemde-editor'));
55
+ function useSimpleMdeReact() {
56
+ const [mounted, setMounted] = useState(false);
57
+ useEffect(() => {
58
+ requestAnimationFrame(() => setMounted(true));
59
+ }, []);
60
+ return mounted ? SimpleMdeReact : null;
61
+ }
62
+ const defaultMdeTools = ["heading", "bold", "italic", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "code", "|", "preview", "side-by-side"];
63
+ function MarkdownInput(props) {
64
+ var _a;
65
+ const {
66
+ value = "",
67
+ onChange,
68
+ elementProps: {
69
+ onBlur,
70
+ onFocus,
71
+ ref
72
+ },
73
+ reactMdeProps: {
74
+ options: mdeCustomOptions,
75
+ ...reactMdeProps
76
+ } = {},
77
+ schemaType
78
+ } = props;
79
+ const client = useClient({
80
+ apiVersion: "2022-01-01"
81
+ });
82
+ const {
83
+ imageUrl
84
+ } = (_a = schemaType.options) != null ? _a : {};
85
+ const imageUpload = useCallback((file, onSuccess, onError) => {
86
+ client.assets.upload("image", file).then(doc => onSuccess(imageUrl ? imageUrl(doc) : "".concat(doc.url, "?w=450"))).catch(e => {
87
+ console.error(e);
88
+ onError(e.message);
89
+ });
90
+ }, [client, imageUrl]);
91
+ const mdeOptions = useMemo(() => {
92
+ return {
93
+ autofocus: false,
94
+ spellChecker: false,
95
+ sideBySideFullscreen: false,
96
+ uploadImage: true,
97
+ imageUploadFunction: imageUpload,
98
+ toolbar: defaultMdeTools,
99
+ status: false,
100
+ ...mdeCustomOptions
101
+ };
102
+ }, [imageUpload, mdeCustomOptions]);
103
+ const handleChange = useCallback(newValue => {
104
+ onChange(PatchEvent.from(newValue ? set(newValue) : unset()));
105
+ }, [onChange]);
106
+ const SimpleMdeReact = useSimpleMdeReact();
107
+ return /* @__PURE__ */jsx(MarkdownInputStyles, {
108
+ children: SimpleMdeReact && /* @__PURE__ */jsx(Suspense, {
109
+ fallback: /* @__PURE__ */jsx(Box, {
110
+ padding: 3,
111
+ children: /* @__PURE__ */jsx(Text, {
112
+ children: "Loading editor..."
113
+ })
114
+ }),
115
+ children: /* @__PURE__ */jsx(SimpleMdeReact, {
116
+ ...reactMdeProps,
117
+ ref,
118
+ value,
119
+ onChange: handleChange,
120
+ onBlur,
121
+ onFocus,
122
+ options: mdeOptions,
123
+ spellCheck: false
124
+ })
125
+ })
126
+ });
127
+ }
128
+ const markdownTypeName = "markdown";
129
+ const markdownSchemaType = defineType({
130
+ type: "string",
131
+ name: markdownTypeName,
132
+ title: "Markdown",
133
+ components: {
134
+ input: MarkdownInput
135
+ }
136
+ });
137
+ const markdownSchema = definePlugin(config => {
138
+ return {
139
+ name: "markdown-editor",
140
+ schema: {
141
+ types: [config && config.input ? {
142
+ ...markdownSchemaType,
143
+ components: {
144
+ input: config.input
145
+ }
146
+ } : markdownSchemaType]
147
+ }
148
+ };
149
+ });
150
+ export { MarkdownInput, defaultMdeTools, markdownSchema, markdownSchemaType };
151
+ //# sourceMappingURL=plugin-ca10aa4c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-ca10aa4c.js","sources":["../../src/components/MarkdownInputStyles.tsx","../../src/components/useSimpleMdeReact.tsx","../../src/components/MarkdownInput.tsx","../../src/schema.ts","../../src/plugin.tsx"],"sourcesContent":["import styled from 'styled-components'\nimport {Box} from '@sanity/ui'\n\nexport const MarkdownInputStyles = styled(Box)`\n & .CodeMirror.CodeMirror {\n color: ${({theme}) => theme.sanity.color.card.enabled.fg};\n border-color: ${({theme}) => theme.sanity.color.card.enabled.border};\n background-color: inherit;\n }\n\n & .cm-s-easymde .CodeMirror-cursor {\n border-color: ${({theme}) => theme.sanity.color.card.enabled.fg};\n }\n\n & .editor-toolbar,\n .editor-preview-side {\n border-color: ${({theme}) => theme.sanity.color.card.enabled.border};\n }\n\n & .CodeMirror-focused .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ${({theme}) => theme.sanity.color.selectable.primary.hovered.bg};\n }\n\n & .CodeMirror-selected.CodeMirror-selected.CodeMirror-selected {\n background-color: ${({theme}) => theme.sanity.color.card.enabled.bg};\n }\n\n & .editor-toolbar > * {\n color: ${({theme}) => theme.sanity.color.card.enabled.fg};\n }\n\n & .editor-toolbar > .active,\n .editor-toolbar > button:hover,\n .editor-preview pre,\n .cm-s-easymde .cm-comment {\n background-color: ${({theme}) => theme.sanity.color.card.enabled.bg};\n }\n\n & .editor-preview {\n background-color: ${({theme}) => theme.sanity.color.card.enabled.bg};\n\n & h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: revert;\n }\n\n & ul,\n li {\n list-style: revert;\n padding: revert;\n }\n\n & a {\n text-decoration: revert;\n }\n }\n`\n","import {lazy, useEffect, useState} from 'react'\n\nexport const SimpleMdeReact = lazy(() => import('react-simplemde-editor'))\n\nexport function useSimpleMdeReact() {\n const [mounted, setMounted] = useState(false)\n useEffect(() => {\n requestAnimationFrame(() => setMounted(true))\n }, [])\n\n return mounted ? SimpleMdeReact : null\n}\n","import {type Options as EasyMdeOptions} from 'easymde'\nimport React, {Suspense, useCallback, useMemo} from 'react'\n// dont import non-types here, it will break SSR on next\nimport type {SimpleMDEReactProps} from 'react-simplemde-editor'\nimport {PatchEvent, set, StringInputProps, unset, useClient} from 'sanity'\nimport {MarkdownOptions} from '../schema'\nimport {MarkdownInputStyles} from './MarkdownInputStyles'\nimport {useSimpleMdeReact} from './useSimpleMdeReact'\nimport {Box, Text} from '@sanity/ui'\n\nexport interface MarkdownInputProps extends StringInputProps {\n /**\n * These are passed along directly to\n *\n * Note: MarkdownInput sets certain reactMdeProps.options by default.\n * These will be merged with any custom options.\n * */\n reactMdeProps?: Omit<SimpleMDEReactProps, 'value' | 'onChange'>\n}\n\nexport const defaultMdeTools: EasyMdeOptions['toolbar'] = [\n 'heading',\n 'bold',\n 'italic',\n '|',\n 'quote',\n 'unordered-list',\n 'ordered-list',\n '|',\n 'link',\n 'image',\n 'code',\n '|',\n 'preview',\n 'side-by-side',\n]\n\nexport function MarkdownInput(props: MarkdownInputProps) {\n const {\n value = '',\n onChange,\n elementProps: {onBlur, onFocus, ref},\n reactMdeProps: {options: mdeCustomOptions, ...reactMdeProps} = {},\n schemaType,\n } = props\n const client = useClient({apiVersion: '2022-01-01'})\n const {imageUrl} = (schemaType.options as MarkdownOptions | undefined) ?? {}\n\n const imageUpload = useCallback(\n (file: File, onSuccess: (url: string) => void, onError: (error: string) => void) => {\n client.assets\n .upload('image', file)\n .then((doc) => onSuccess(imageUrl ? imageUrl(doc) : `${doc.url}?w=450`))\n .catch((e) => {\n console.error(e)\n onError(e.message)\n })\n },\n [client, imageUrl]\n )\n\n const mdeOptions: EasyMdeOptions = useMemo(() => {\n return {\n autofocus: false,\n spellChecker: false,\n sideBySideFullscreen: false,\n uploadImage: true,\n imageUploadFunction: imageUpload,\n toolbar: defaultMdeTools,\n status: false,\n ...mdeCustomOptions,\n }\n }, [imageUpload, mdeCustomOptions])\n\n const handleChange = useCallback(\n (newValue: string) => {\n onChange(PatchEvent.from(newValue ? set(newValue) : unset()))\n },\n [onChange]\n )\n\n const SimpleMdeReact = useSimpleMdeReact()\n\n return (\n <MarkdownInputStyles>\n {SimpleMdeReact && (\n <Suspense\n fallback={\n <Box padding={3}>\n <Text>Loading editor...</Text>\n </Box>\n }\n >\n <SimpleMdeReact\n {...reactMdeProps}\n ref={ref}\n value={value}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n options={mdeOptions}\n spellCheck={false}\n />\n </Suspense>\n )}\n </MarkdownInputStyles>\n )\n}\n","import {defineType, StringDefinition} from 'sanity'\nimport {MarkdownInput} from './components/MarkdownInput'\nimport {SanityImageAssetDocument} from '@sanity/client'\n\nexport const markdownTypeName = 'markdown' as const\n\nexport interface MarkdownOptions {\n /**\n * Used to create image url for any uploaded image.\n * The function will be invoked whenever an image is pasted or dragged into the\n * markdown editor, after upload completes.\n *\n * The default implementation uses\n * ```js\n * imageAsset => `${imageAsset.url}?w=450`\n * ```\n * ## Example\n * ```js\n * {\n * imageUrl: imageAsset => `${imageAsset.url}?w=400&h=400`\n * }\n * ```\n * @param imageAsset\n */\n imageUrl?: (imageAsset: SanityImageAssetDocument) => string\n}\n\n/**\n * @public\n */\nexport interface MarkdownDefinition extends Omit<StringDefinition, 'type' | 'fields' | 'options'> {\n type: typeof markdownTypeName\n options?: MarkdownOptions\n}\n\ndeclare module '@sanity/types' {\n // makes type: 'markdown' narrow correctly when using defineType/defineField/defineArrayMember\n export interface IntrinsicDefinitions {\n markdown: MarkdownDefinition\n }\n}\n\nexport const markdownSchemaType = defineType({\n type: 'string',\n name: markdownTypeName,\n title: 'Markdown',\n components: {input: MarkdownInput},\n})\n","import {definePlugin, StringInputProps} from 'sanity'\nimport {markdownSchemaType} from './schema'\nimport {ReactElement} from 'react'\n\nexport interface MarkdownConfig {\n /**\n * When provided, will replace the default input component.\n *\n * Use this to customize MarkdownInput by wrapping it in a custom component,\n * and provide any custom props for https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor\n * via the `reactMdeProps` prop.\n *\n * ### Example\n *\n * ```tsx\n * // CustomMarkdownInput.tsx\n * import { MarkdownInput, MarkdownInputProps } from 'sanity-plugin-markdown'\n *\n * export function CustomMarkdownInput(props) {\n * const reactMdeProps: MarkdownInputProps['reactMdeProps'] =\n * useMemo(() => {\n * return {\n * options: {\n * toolbar: ['bold', 'italic'],\n * // more options available, see:\n * // https://github.com/Ionaru/easy-markdown-editor#options-list\n * },\n * // more props available, see:\n * // https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor\n * }\n * }, [])\n *\n * return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />\n * }\n *\n * // studio.config.ts\n * markdownSchema({input: CustomMarkdownInput})\n * ```\n */\n input?: (props: StringInputProps) => ReactElement\n}\n\nexport const markdownSchema = definePlugin((config: MarkdownConfig | void) => {\n return {\n name: 'markdown-editor',\n schema: {\n types: [\n config && config.input\n ? {...markdownSchemaType, components: {input: config.input}}\n : markdownSchemaType,\n ],\n },\n }\n})\n"],"names":["MarkdownInputStyles","styled","Box","_templateObject","_taggedTemplateLiteral","_ref","theme","sanity","color","card","enabled","fg","_ref2","border","_ref3","_ref4","_ref5","selectable","primary","hovered","bg","_ref6","_ref7","_ref8","_ref9","SimpleMdeReact","lazy","useSimpleMdeReact","mounted","setMounted","useState","useEffect","requestAnimationFrame","defaultMdeTools","MarkdownInput","props","_a","value","onChange","elementProps","onBlur","onFocus","ref","reactMdeProps","options","mdeCustomOptions","schemaType","client","useClient","apiVersion","imageUrl","imageUpload","useCallback","file","onSuccess","onError","assets","upload","then","doc","concat","url","catch","e","console","error","message","mdeOptions","useMemo","autofocus","spellChecker","sideBySideFullscreen","uploadImage","imageUploadFunction","toolbar","status","handleChange","newValue","PatchEvent","from","set","unset","jsx","children","Suspense","fallback","padding","Text","spellCheck","markdownTypeName","markdownSchemaType","defineType","type","name","title","components","input","markdownSchema","definePlugin","config","schema","types"],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,108 @@
1
+ /// <reference types="react" />
2
+
3
+ import {Options} from 'easymde'
4
+ import {Plugin as Plugin_2} from 'sanity'
5
+ import {ReactElement} from 'react'
6
+ import {SanityImageAssetDocument} from '@sanity/client'
7
+ import type {SimpleMDEReactProps} from 'react-simplemde-editor'
8
+ import {StringDefinition} from 'sanity'
9
+ import {StringInputProps} from 'sanity'
10
+
11
+ export declare const defaultMdeTools: Options['toolbar']
12
+
13
+ export declare interface MarkdownConfig {
14
+ /**
15
+ * When provided, will replace the default input component.
16
+ *
17
+ * Use this to customize MarkdownInput by wrapping it in a custom component,
18
+ * and provide any custom props for https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor
19
+ * via the `reactMdeProps` prop.
20
+ *
21
+ * ### Example
22
+ *
23
+ * ```tsx
24
+ * // CustomMarkdownInput.tsx
25
+ * import { MarkdownInput, MarkdownInputProps } from 'sanity-plugin-markdown'
26
+ *
27
+ * export function CustomMarkdownInput(props) {
28
+ * const reactMdeProps: MarkdownInputProps['reactMdeProps'] =
29
+ * useMemo(() => {
30
+ * return {
31
+ * options: {
32
+ * toolbar: ['bold', 'italic'],
33
+ * // more options available, see:
34
+ * // https://github.com/Ionaru/easy-markdown-editor#options-list
35
+ * },
36
+ * // more props available, see:
37
+ * // https://github.com/RIP21/react-simplemde-editor#react-simplemde-easymde-markdown-editor
38
+ * }
39
+ * }, [])
40
+ *
41
+ * return <MarkdownInput {...props} reactMdeProps={reactMdeProps} />
42
+ * }
43
+ *
44
+ * // studio.config.ts
45
+ * markdownSchema({input: CustomMarkdownInput})
46
+ * ```
47
+ */
48
+ input?: (props: StringInputProps) => ReactElement
49
+ }
50
+
51
+ /**
52
+ * @public
53
+ */
54
+ export declare interface MarkdownDefinition
55
+ extends Omit<StringDefinition, 'type' | 'fields' | 'options'> {
56
+ type: typeof markdownTypeName
57
+ options?: MarkdownOptions
58
+ }
59
+
60
+ export declare function MarkdownInput(props: MarkdownInputProps): JSX.Element
61
+
62
+ export declare interface MarkdownInputProps extends StringInputProps {
63
+ /**
64
+ * These are passed along directly to
65
+ *
66
+ * Note: MarkdownInput sets certain reactMdeProps.options by default.
67
+ * These will be merged with any custom options.
68
+ * */
69
+ reactMdeProps?: Omit<SimpleMDEReactProps, 'value' | 'onChange'>
70
+ }
71
+
72
+ declare interface MarkdownOptions {
73
+ /**
74
+ * Used to create image url for any uploaded image.
75
+ * The function will be invoked whenever an image is pasted or dragged into the
76
+ * markdown editor, after upload completes.
77
+ *
78
+ * The default implementation uses
79
+ * ```js
80
+ * imageAsset => `${imageAsset.url}?w=450`
81
+ * ```
82
+ * ## Example
83
+ * ```js
84
+ * {
85
+ * imageUrl: imageAsset => `${imageAsset.url}?w=400&h=400`
86
+ * }
87
+ * ```
88
+ * @param imageAsset
89
+ */
90
+ imageUrl?: (imageAsset: SanityImageAssetDocument) => string
91
+ }
92
+
93
+ export declare const markdownSchema: Plugin_2<void | MarkdownConfig>
94
+
95
+ export declare const markdownSchemaType: {
96
+ type: 'string'
97
+ name: 'markdown'
98
+ } & Omit<StringDefinition, 'preview'>
99
+
100
+ declare const markdownTypeName: 'markdown'
101
+
102
+ export {}
103
+
104
+ declare module '@sanity/types' {
105
+ interface IntrinsicDefinitions {
106
+ markdown: MarkdownDefinition
107
+ }
108
+ }