sanity-plugin-markdown 3.0.0-v3-studio.0 → 3.0.0-v3-studio.2
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 +1 -1
- package/README.md +16 -17
- package/lib/index.d.ts +1 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +47 -135
- package/lib/index.js.map +1 -1
- package/lib/index.modern.js +50 -138
- package/lib/index.modern.js.map +1 -1
- package/package.json +16 -16
- package/src/components/Editor.tsx +28 -120
- package/src/index.ts +5 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -10,9 +10,15 @@
|
|
|
10
10
|
|
|
11
11
|
A Markdown editor with preview for Sanity Studio.
|
|
12
12
|
|
|
13
|
-
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.
|
|
13
|
+
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.
|
|
14
|
+
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).
|
|
15
|
+
|
|
16
|
+
### Known issues with the current v3 version
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
The v2 version used react-mde for editing. The current v3 version @uiw/react-md-editor. This may change before GA.
|
|
19
|
+
|
|
20
|
+
At the moment the v3 version does not have drag-and-drop image upload support.
|
|
21
|
+
You can still add markdown image tags, but you will have to get the image url yourself for now.
|
|
16
22
|
|
|
17
23
|
## Installation
|
|
18
24
|
|
|
@@ -68,22 +74,15 @@ See LICENSE
|
|
|
68
74
|
|
|
69
75
|
## Develop & test
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
npm run link-watch
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
In another shell, `cd` to your test studio and run:
|
|
77
|
+
This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
|
|
78
|
+
with default configuration for build & watch scripts.
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```
|
|
80
|
+
See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
|
|
81
|
+
on how to run this plugin with hotreload in the studio.
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
triggering hotreload. Yalc avoids issues with react-hooks that are typical when using yarn/npm link.
|
|
83
|
+
### Release new version
|
|
85
84
|
|
|
86
|
-
|
|
85
|
+
Run ["CI & Release" workflow](https://github.com/sanity-io/sanity-plugin-markdown/actions).
|
|
86
|
+
Make sure to select the main/v3 branch and check "Release new version".
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
with default configuration for build & watch scripts.
|
|
88
|
+
Semantic release will only release on configured branches, so it is safe to run release on any branch.
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import React from "react";
|
|
3
|
-
export const MarkdownEditor: React.ForwardRefExoticComponent<StringInputProps<import("sanity").StringSchemaType> & React.RefAttributes<any>>;
|
|
1
|
+
export const MarkdownEditor: import("react").ForwardRefExoticComponent<import("sanity").StringInputProps<import("sanity").StringSchemaType> & import("react").RefAttributes<any>>;
|
|
4
2
|
export const markdownSchema: import("sanity").Plugin<void>;
|
|
5
3
|
|
|
6
4
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"
|
|
1
|
+
{"mappings":"AEIA,OAAA,MAAM,oKAAuB,CAAA;AAI7B,OAAO,MAAM,6CAcX,CAAA","sources":["src/src/hooks/useDebounce.ts","src/src/components/Editor.tsx","src/src/index.ts","src/index.ts"],"sourcesContent":[null,null,null,"import {MarkdownEditor as Editor} from './components/Editor'\nimport {createPlugin, defineType} from 'sanity'\n\n// re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:\nconst MarkdownEditor = Editor\n\nexport {MarkdownEditor}\n\nexport const markdownSchema = createPlugin({\n name: 'markdown-editor',\n schema: {\n types: [\n defineType({\n type: 'string' as const,\n name: 'markdown',\n title: 'Markdown',\n components: {\n input: MarkdownEditor,\n },\n }),\n ],\n },\n})\n"],"names":[],"version":3,"file":"index.d.ts.map","sourceRoot":"../"}
|
package/lib/index.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
var $3KLdq$sanity = require("sanity");
|
|
2
2
|
var $3KLdq$reactjsxruntime = require("react/jsx-runtime");
|
|
3
|
-
var $3KLdq$
|
|
4
|
-
var $3KLdq$reactmarkdown = require("react-markdown");
|
|
5
|
-
var $3KLdq$remarkgfm = require("remark-gfm");
|
|
6
|
-
var $3KLdq$reachautoid = require("@reach/auto-id");
|
|
7
|
-
require("react-mde/lib/styles/css/react-mde-all.css");
|
|
3
|
+
var $3KLdq$uiwreactmdeditor = require("@uiw/react-md-editor");
|
|
8
4
|
var $3KLdq$sanityform = require("sanity/form");
|
|
9
5
|
var $3KLdq$react = require("react");
|
|
10
|
-
var $3KLdq$styledcomponents = require("styled-components");
|
|
11
6
|
var $3KLdq$sanityui = require("@sanity/ui");
|
|
7
|
+
var $3KLdq$rehypesanitize = require("rehype-sanitize");
|
|
12
8
|
|
|
13
9
|
function $parcel$export(e, n, v, s) {
|
|
14
10
|
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
@@ -17,11 +13,8 @@ function $parcel$interopDefault(a) {
|
|
|
17
13
|
return a && a.__esModule ? a.default : a;
|
|
18
14
|
}
|
|
19
15
|
|
|
16
|
+
$parcel$export(module.exports, "MarkdownEditor", () => $244e63ca53592e4d$export$18a9461578883ec4);
|
|
20
17
|
$parcel$export(module.exports, "markdownSchema", () => $244e63ca53592e4d$export$f225414958dd8925);
|
|
21
|
-
$parcel$export(module.exports, "MarkdownEditor", () => $067e75d167fd097d$export$18a9461578883ec4);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
18
|
|
|
26
19
|
|
|
27
20
|
|
|
@@ -44,84 +37,11 @@ function $84fd43422be26bd7$export$2e2bcd8739ae039(value, delay) {
|
|
|
44
37
|
|
|
45
38
|
|
|
46
39
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const $067e75d167fd097d$var$Preview = ({ markdown: markdown })=>{
|
|
50
|
-
return /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, ($parcel$interopDefault($3KLdq$reactmarkdown))), {
|
|
51
|
-
plugins: [
|
|
52
|
-
(0, ($parcel$interopDefault($3KLdq$remarkgfm)))
|
|
53
|
-
],
|
|
54
|
-
children: markdown
|
|
55
|
-
});
|
|
56
|
-
};
|
|
57
|
-
const $067e75d167fd097d$var$defaultToolbarCommands = [
|
|
58
|
-
[
|
|
59
|
-
"header",
|
|
60
|
-
"bold",
|
|
61
|
-
"italic",
|
|
62
|
-
"strikethrough"
|
|
63
|
-
],
|
|
64
|
-
[
|
|
65
|
-
"link",
|
|
66
|
-
"quote",
|
|
67
|
-
"code"
|
|
68
|
-
],
|
|
69
|
-
[
|
|
70
|
-
"unordered-list",
|
|
71
|
-
"ordered-list",
|
|
72
|
-
"checked-list"
|
|
73
|
-
],
|
|
74
|
-
];
|
|
75
|
-
// !important is used whenever we need to override inline styles for an element
|
|
76
|
-
const $067e75d167fd097d$var$MarkdownTheme = (0, ($parcel$interopDefault($3KLdq$styledcomponents))).div`
|
|
77
|
-
& .react-mde {
|
|
78
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
& .mde-text {
|
|
82
|
-
background: ${({ studioTheme: studioTheme })=>studioTheme.color.input.default.enabled.bg} !important;
|
|
83
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.input.default.enabled.fg} !important;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
& .mde-header {
|
|
87
|
-
background: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.bg};
|
|
88
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.fg};
|
|
89
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
90
|
-
|
|
91
|
-
& button,
|
|
92
|
-
.mde-header-item.mde-header-item.mde-header-item button {
|
|
93
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.button.bleed.default.enabled.fg};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
& button.selected {
|
|
97
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
& .image-tip {
|
|
102
|
-
background: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.bg};
|
|
103
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.muted.default.enabled.fg};
|
|
104
|
-
font-family: ${({ studioTheme: studioTheme })=>studioTheme.fonts.text.family};
|
|
105
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
106
|
-
}
|
|
107
|
-
`;
|
|
108
40
|
const $067e75d167fd097d$export$18a9461578883ec4 = /*#__PURE__*/ (0, $3KLdq$react.forwardRef)(function MarkdownEditor(props, ref) {
|
|
109
|
-
const {
|
|
110
|
-
const options = type.options;
|
|
111
|
-
const [selectedTab, setSelectedTab] = (0, $3KLdq$react.useState)("write");
|
|
41
|
+
const { value: value = "" , onChange: onChange , elementProps: { onBlur: onBlur , onFocus: onFocus } , readOnly: readOnly , } = props;
|
|
112
42
|
const [editedValue, setEditedValue] = (0, $3KLdq$react.useState)(value);
|
|
113
43
|
const debouncedValue = (0, $84fd43422be26bd7$export$2e2bcd8739ae039)(editedValue, 100);
|
|
114
|
-
const
|
|
115
|
-
const sanityClient = (0, $3KLdq$sanity.useClient)();
|
|
116
|
-
// Conditionally update textarea styles based on read only access.
|
|
117
|
-
// It's also possible to define inline styles via `childProps.textArea.style` on `<ReactMde />`,
|
|
118
|
-
// but this will override any dynamically created styles provided by the component itself.
|
|
119
|
-
(0, $3KLdq$react.useEffect)(()=>{
|
|
120
|
-
if (textarea.current) textarea.current.style.backgroundColor = readOnly ? "rgba(240,240,240)" : "rgba(255,255,255)";
|
|
121
|
-
}, [
|
|
122
|
-
textarea,
|
|
123
|
-
readOnly
|
|
124
|
-
]);
|
|
44
|
+
// const client = useClient({apiVersion: '2021-03-25'})
|
|
125
45
|
(0, $3KLdq$react.useEffect)(()=>{
|
|
126
46
|
setEditedValue(value);
|
|
127
47
|
}, [
|
|
@@ -139,63 +59,55 @@ const $067e75d167fd097d$export$18a9461578883ec4 = /*#__PURE__*/ (0, $3KLdq$react
|
|
|
139
59
|
debouncedValue,
|
|
140
60
|
onChange
|
|
141
61
|
]);
|
|
142
|
-
const saveImage = async function*(data) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const inputId = (0, $3KLdq$reachautoid.useId)();
|
|
158
|
-
const { sanity: studioTheme } = (0, $3KLdq$sanityui.useTheme)();
|
|
159
|
-
/*
|
|
160
|
-
Assign our forwarded ref to a wrapper element.
|
|
161
|
-
Ideally, this should be assigned to the textarea inside <ReactMde /> component.
|
|
162
|
-
Whilst `react-mde` does allow you to target individual sub-components' refs,
|
|
163
|
-
it will complain if you try and assign a forwarded ref.
|
|
164
|
-
*/ return /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)("div", {
|
|
62
|
+
/* const saveImage = async function* (data: any) {
|
|
63
|
+
|
|
64
|
+
let success = true
|
|
65
|
+
const result = await client.assets
|
|
66
|
+
.upload('image', data)
|
|
67
|
+
.then((doc) => `${doc.url}?w=450`)
|
|
68
|
+
.catch(() => {
|
|
69
|
+
success = false
|
|
70
|
+
return `Error: Could not upload file. Only images are supported.`
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
yield result
|
|
74
|
+
return success
|
|
75
|
+
}*/ const { sanity: studioTheme } = (0, $3KLdq$sanityui.useTheme)();
|
|
76
|
+
return /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)("div", {
|
|
165
77
|
ref: ref,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
textArea: {
|
|
178
|
-
id: inputId,
|
|
179
|
-
onBlur: onBlur,
|
|
180
|
-
onFocus: onFocus
|
|
181
|
-
},
|
|
182
|
-
writeButton: {
|
|
183
|
-
tabIndex: -1
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
paste: {
|
|
187
|
-
saveImage: saveImage
|
|
188
|
-
},
|
|
189
|
-
refs: {
|
|
190
|
-
textarea: textarea
|
|
191
|
-
}
|
|
78
|
+
"data-color-mode": studioTheme.color.dark ? "dark" : "light",
|
|
79
|
+
children: readOnly ? /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, $3KLdq$sanityui.Card), {
|
|
80
|
+
border: true,
|
|
81
|
+
padding: 3,
|
|
82
|
+
children: /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, ($parcel$interopDefault($3KLdq$uiwreactmdeditor))).Markdown, {
|
|
83
|
+
source: value,
|
|
84
|
+
rehypePlugins: [
|
|
85
|
+
[
|
|
86
|
+
(0, ($parcel$interopDefault($3KLdq$rehypesanitize)))
|
|
87
|
+
]
|
|
88
|
+
]
|
|
192
89
|
})
|
|
90
|
+
}) : /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, ($parcel$interopDefault($3KLdq$uiwreactmdeditor))), {
|
|
91
|
+
value: editedValue,
|
|
92
|
+
onChange: setEditedValue,
|
|
93
|
+
onBlur: onBlur,
|
|
94
|
+
onFocus: onFocus,
|
|
95
|
+
previewOptions: {
|
|
96
|
+
rehypePlugins: [
|
|
97
|
+
[
|
|
98
|
+
(0, ($parcel$interopDefault($3KLdq$rehypesanitize)))
|
|
99
|
+
]
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
preview: "edit"
|
|
193
103
|
})
|
|
194
104
|
});
|
|
195
105
|
});
|
|
196
106
|
|
|
197
107
|
|
|
198
108
|
|
|
109
|
+
// re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:
|
|
110
|
+
const $244e63ca53592e4d$export$18a9461578883ec4 = (0, $067e75d167fd097d$export$18a9461578883ec4);
|
|
199
111
|
const $244e63ca53592e4d$export$f225414958dd8925 = (0, $3KLdq$sanity.createPlugin)({
|
|
200
112
|
name: "markdown-editor",
|
|
201
113
|
schema: {
|
|
@@ -205,7 +117,7 @@ const $244e63ca53592e4d$export$f225414958dd8925 = (0, $3KLdq$sanity.createPlugin
|
|
|
205
117
|
name: "markdown",
|
|
206
118
|
title: "Markdown",
|
|
207
119
|
components: {
|
|
208
|
-
input:
|
|
120
|
+
input: $244e63ca53592e4d$export$18a9461578883ec4
|
|
209
121
|
}
|
|
210
122
|
}),
|
|
211
123
|
]
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["src/index.ts","src/components/Editor.tsx","src/hooks/useDebounce.ts"],"sourcesContent":["import {MarkdownEditor} from './components/Editor'\nimport {createPlugin, defineType} from 'sanity'\n\nexport {MarkdownEditor}\n\nexport const markdownSchema = createPlugin({\n name: 'markdown-editor',\n schema: {\n types: [\n defineType({\n type: 'string',\n name: 'markdown',\n title: 'Markdown',\n components: {\n input: MarkdownEditor,\n },\n }),\n ],\n },\n})\n","import ReactMde from 'react-mde'\nimport ReactMarkdown from 'react-markdown'\nimport gfm from 'remark-gfm'\nimport {useId} from '@reach/auto-id'\n\nimport useDebounce from '../hooks/useDebounce'\nimport 'react-mde/lib/styles/css/react-mde-all.css'\nimport {PatchEvent, set, unset} from 'sanity/form'\nimport {StringInputProps, useClient} from 'sanity'\nimport React, {\n FC,\n forwardRef,\n PropsWithChildren,\n Ref,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {ToolbarCommands} from 'react-mde/lib/definitions/types'\nimport styled from 'styled-components'\nimport {Theme, useTheme} from '@sanity/ui'\n\nconst Preview = ({markdown}: {markdown: string}) => {\n return <ReactMarkdown plugins={[gfm]}>{markdown}</ReactMarkdown>\n}\n\nconst defaultToolbarCommands = [\n ['header', 'bold', 'italic', 'strikethrough'],\n ['link', 'quote', 'code'],\n ['unordered-list', 'ordered-list', 'checked-list'],\n]\n\ntype SanityTheme = Theme['sanity']\n\ntype Style = PropsWithChildren<{\n studioTheme: SanityTheme\n}>\n\n// !important is used whenever we need to override inline styles for an element\nconst MarkdownTheme: FC<Style> = styled.div`\n & .react-mde {\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n }\n\n & .mde-text {\n background: ${({studioTheme}: Style) => studioTheme.color.input.default.enabled.bg} !important;\n color: ${({studioTheme}: Style) => studioTheme.color.input.default.enabled.fg} !important;\n }\n\n & .mde-header {\n background: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg};\n color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.fg};\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n\n & button,\n .mde-header-item.mde-header-item.mde-header-item button {\n color: ${({studioTheme}: Style) => studioTheme.color.button.bleed.default.enabled.fg};\n }\n\n & button.selected {\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n }\n }\n\n & .image-tip {\n background: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg};\n color: ${({studioTheme}: Style) => studioTheme.color.muted.default.enabled.fg};\n font-family: ${({studioTheme}: Style) => studioTheme.fonts.text.family};\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n }\n`\n\nexport const MarkdownEditor = forwardRef(function MarkdownEditor(\n props: StringInputProps,\n ref: Ref<any>\n) {\n const {schemaType: type, value = '', onBlur, onChange, onFocus, readOnly} = props\n const options: {toolbar?: ToolbarCommands} | undefined = type.options as any\n const [selectedTab, setSelectedTab] = useState<'write' | 'preview'>('write')\n const [editedValue, setEditedValue] = useState(value)\n const debouncedValue = useDebounce(editedValue, 100)\n const textarea = useRef<HTMLTextAreaElement>(null)\n const sanityClient = useClient()\n\n // Conditionally update textarea styles based on read only access.\n // It's also possible to define inline styles via `childProps.textArea.style` on `<ReactMde />`,\n // but this will override any dynamically created styles provided by the component itself.\n useEffect(() => {\n if (textarea.current) {\n textarea.current.style.backgroundColor = readOnly ? 'rgba(240,240,240)' : 'rgba(255,255,255)'\n }\n }, [textarea, readOnly])\n\n useEffect(() => {\n setEditedValue(value)\n }, [value])\n\n useEffect(() => {\n if (!debouncedValue && value) {\n onChange(PatchEvent.from([unset()]))\n } else if (debouncedValue !== value) {\n onChange(PatchEvent.from([set(debouncedValue)]))\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedValue, onChange])\n\n const saveImage = async function* (data: any) {\n const client = sanityClient.withConfig({apiVersion: '2021-03-25'})\n\n let success = true\n const result = await client.assets\n .upload('image', data)\n .then((doc) => `${doc.url}?w=450`)\n .catch(() => {\n success = false\n return `Error: Could not upload file. Only images are supported.`\n })\n\n yield result\n return success\n }\n\n const generatePreview = useCallback(\n (markdown: string) => Promise.resolve(<Preview markdown={markdown} />),\n []\n )\n\n const inputId = useId()\n const {sanity: studioTheme} = useTheme()\n /*\n Assign our forwarded ref to a wrapper element.\n Ideally, this should be assigned to the textarea inside <ReactMde /> component.\n Whilst `react-mde` does allow you to target individual sub-components' refs,\n it will complain if you try and assign a forwarded ref.\n */\n return (\n <div ref={ref}>\n <MarkdownTheme studioTheme={studioTheme}>\n <ReactMde\n toolbarCommands={options?.toolbar || defaultToolbarCommands}\n value={editedValue}\n onChange={setEditedValue}\n selectedTab={selectedTab}\n onTabChange={setSelectedTab}\n readOnly={readOnly}\n generateMarkdownPreview={generatePreview}\n childProps={{\n textArea: {\n id: inputId,\n onBlur,\n onFocus,\n },\n writeButton: {\n tabIndex: -1,\n },\n }}\n paste={{saveImage}}\n refs={{textarea}}\n />\n </MarkdownTheme>\n </div>\n )\n})\n","import {useState, useEffect} from 'react'\n\nexport default function useDebounce(value: unknown, delay: number) {\n const [debouncedValue, setDebouncedValue] = useState(value)\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value)\n }, delay)\n\n return () => clearTimeout(handler)\n }, [value, delay])\n\n return debouncedValue\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"}
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts","src/components/Editor.tsx","src/hooks/useDebounce.ts"],"sourcesContent":["import {MarkdownEditor as Editor} from './components/Editor'\nimport {createPlugin, defineType} from 'sanity'\n\n// re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:\nconst MarkdownEditor = Editor\n\nexport {MarkdownEditor}\n\nexport const markdownSchema = createPlugin({\n name: 'markdown-editor',\n schema: {\n types: [\n defineType({\n type: 'string' as const,\n name: 'markdown',\n title: 'Markdown',\n components: {\n input: MarkdownEditor,\n },\n }),\n ],\n },\n})\n","import MDEditor from '@uiw/react-md-editor'\nimport useDebounce from '../hooks/useDebounce'\nimport {PatchEvent, set, unset} from 'sanity/form'\nimport {StringInputProps} from 'sanity'\nimport React, {forwardRef, Ref, useEffect, useState} from 'react'\nimport {Card, useTheme} from '@sanity/ui'\nimport rehypeSanitize from 'rehype-sanitize'\n\nexport const MarkdownEditor = forwardRef(function MarkdownEditor(\n props: StringInputProps,\n ref: Ref<any>\n) {\n const {\n value = '',\n onChange,\n elementProps: {onBlur, onFocus},\n readOnly,\n } = props\n const [editedValue, setEditedValue] = useState<string | undefined>(value)\n const debouncedValue = useDebounce(editedValue, 100)\n // const client = useClient({apiVersion: '2021-03-25'})\n\n useEffect(() => {\n setEditedValue(value)\n }, [value])\n\n useEffect(() => {\n if (!debouncedValue && value) {\n onChange(PatchEvent.from([unset()]))\n } else if (debouncedValue !== value) {\n onChange(PatchEvent.from([set(debouncedValue)]))\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedValue, onChange])\n\n /* const saveImage = async function* (data: any) {\n\n let success = true\n const result = await client.assets\n .upload('image', data)\n .then((doc) => `${doc.url}?w=450`)\n .catch(() => {\n success = false\n return `Error: Could not upload file. Only images are supported.`\n })\n\n yield result\n return success\n }*/\n\n const {sanity: studioTheme} = useTheme()\n return (\n <div ref={ref} data-color-mode={studioTheme.color.dark ? 'dark' : 'light'}>\n {readOnly ? (\n <Card border padding={3}>\n <MDEditor.Markdown source={value} rehypePlugins={[[rehypeSanitize]]} />\n </Card>\n ) : (\n <MDEditor\n value={editedValue}\n onChange={setEditedValue}\n onBlur={onBlur}\n onFocus={onFocus}\n previewOptions={{\n rehypePlugins: [[rehypeSanitize]],\n }}\n preview=\"edit\"\n />\n )}\n </div>\n )\n})\n","import {useState, useEffect} from 'react'\n\nexport default function useDebounce(value: unknown, delay: number) {\n const [debouncedValue, setDebouncedValue] = useState(value)\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value)\n }, delay)\n\n return () => clearTimeout(handler)\n }, [value, delay])\n\n return debouncedValue\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"}
|
package/lib/index.modern.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import {createPlugin as $jPEKE$createPlugin, defineType as $jPEKE$defineType
|
|
1
|
+
import {createPlugin as $jPEKE$createPlugin, defineType as $jPEKE$defineType} from "sanity";
|
|
2
2
|
import {jsx as $jPEKE$jsx} from "react/jsx-runtime";
|
|
3
|
-
import $jPEKE$
|
|
4
|
-
import $jPEKE$reactmarkdown from "react-markdown";
|
|
5
|
-
import $jPEKE$remarkgfm from "remark-gfm";
|
|
6
|
-
import {useId as $jPEKE$useId} from "@reach/auto-id";
|
|
7
|
-
import "react-mde/lib/styles/css/react-mde-all.css";
|
|
3
|
+
import $jPEKE$uiwreactmdeditor from "@uiw/react-md-editor";
|
|
8
4
|
import {PatchEvent as $jPEKE$PatchEvent, unset as $jPEKE$unset, set as $jPEKE$set} from "sanity/form";
|
|
9
|
-
import {forwardRef as $jPEKE$forwardRef, useState as $jPEKE$useState,
|
|
10
|
-
import $jPEKE$
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
import {forwardRef as $jPEKE$forwardRef, useState as $jPEKE$useState, useEffect as $jPEKE$useEffect} from "react";
|
|
6
|
+
import {useTheme as $jPEKE$useTheme, Card as $jPEKE$Card} from "@sanity/ui";
|
|
7
|
+
import $jPEKE$rehypesanitize from "rehype-sanitize";
|
|
15
8
|
|
|
16
9
|
|
|
17
10
|
|
|
@@ -35,84 +28,11 @@ function $a9f5cf746146e5f0$export$2e2bcd8739ae039(value, delay) {
|
|
|
35
28
|
|
|
36
29
|
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const $483dd42bf797352b$var$Preview = ({ markdown: markdown })=>{
|
|
41
|
-
return /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$reactmarkdown), {
|
|
42
|
-
plugins: [
|
|
43
|
-
(0, $jPEKE$remarkgfm)
|
|
44
|
-
],
|
|
45
|
-
children: markdown
|
|
46
|
-
});
|
|
47
|
-
};
|
|
48
|
-
const $483dd42bf797352b$var$defaultToolbarCommands = [
|
|
49
|
-
[
|
|
50
|
-
"header",
|
|
51
|
-
"bold",
|
|
52
|
-
"italic",
|
|
53
|
-
"strikethrough"
|
|
54
|
-
],
|
|
55
|
-
[
|
|
56
|
-
"link",
|
|
57
|
-
"quote",
|
|
58
|
-
"code"
|
|
59
|
-
],
|
|
60
|
-
[
|
|
61
|
-
"unordered-list",
|
|
62
|
-
"ordered-list",
|
|
63
|
-
"checked-list"
|
|
64
|
-
],
|
|
65
|
-
];
|
|
66
|
-
// !important is used whenever we need to override inline styles for an element
|
|
67
|
-
const $483dd42bf797352b$var$MarkdownTheme = (0, $jPEKE$styledcomponents).div`
|
|
68
|
-
& .react-mde {
|
|
69
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
& .mde-text {
|
|
73
|
-
background: ${({ studioTheme: studioTheme })=>studioTheme.color.input.default.enabled.bg} !important;
|
|
74
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.input.default.enabled.fg} !important;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
& .mde-header {
|
|
78
|
-
background: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.bg};
|
|
79
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.fg};
|
|
80
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
81
|
-
|
|
82
|
-
& button,
|
|
83
|
-
.mde-header-item.mde-header-item.mde-header-item button {
|
|
84
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.button.bleed.default.enabled.fg};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
& button.selected {
|
|
88
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
& .image-tip {
|
|
93
|
-
background: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.bg};
|
|
94
|
-
color: ${({ studioTheme: studioTheme })=>studioTheme.color.muted.default.enabled.fg};
|
|
95
|
-
font-family: ${({ studioTheme: studioTheme })=>studioTheme.fonts.text.family};
|
|
96
|
-
border-color: ${({ studioTheme: studioTheme })=>studioTheme.color.card.enabled.border};
|
|
97
|
-
}
|
|
98
|
-
`;
|
|
99
31
|
const $483dd42bf797352b$export$18a9461578883ec4 = /*#__PURE__*/ (0, $jPEKE$forwardRef)(function MarkdownEditor(props, ref) {
|
|
100
|
-
const {
|
|
101
|
-
const options = type.options;
|
|
102
|
-
const [selectedTab, setSelectedTab] = (0, $jPEKE$useState)("write");
|
|
32
|
+
const { value: value = "" , onChange: onChange , elementProps: { onBlur: onBlur , onFocus: onFocus } , readOnly: readOnly , } = props;
|
|
103
33
|
const [editedValue, setEditedValue] = (0, $jPEKE$useState)(value);
|
|
104
34
|
const debouncedValue = (0, $a9f5cf746146e5f0$export$2e2bcd8739ae039)(editedValue, 100);
|
|
105
|
-
const
|
|
106
|
-
const sanityClient = (0, $jPEKE$useClient)();
|
|
107
|
-
// Conditionally update textarea styles based on read only access.
|
|
108
|
-
// It's also possible to define inline styles via `childProps.textArea.style` on `<ReactMde />`,
|
|
109
|
-
// but this will override any dynamically created styles provided by the component itself.
|
|
110
|
-
(0, $jPEKE$useEffect)(()=>{
|
|
111
|
-
if (textarea.current) textarea.current.style.backgroundColor = readOnly ? "rgba(240,240,240)" : "rgba(255,255,255)";
|
|
112
|
-
}, [
|
|
113
|
-
textarea,
|
|
114
|
-
readOnly
|
|
115
|
-
]);
|
|
35
|
+
// const client = useClient({apiVersion: '2021-03-25'})
|
|
116
36
|
(0, $jPEKE$useEffect)(()=>{
|
|
117
37
|
setEditedValue(value);
|
|
118
38
|
}, [
|
|
@@ -130,63 +50,55 @@ const $483dd42bf797352b$export$18a9461578883ec4 = /*#__PURE__*/ (0, $jPEKE$forwa
|
|
|
130
50
|
debouncedValue,
|
|
131
51
|
onChange
|
|
132
52
|
]);
|
|
133
|
-
const saveImage = async function*(data) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const inputId = (0, $jPEKE$useId)();
|
|
149
|
-
const { sanity: studioTheme } = (0, $jPEKE$useTheme)();
|
|
150
|
-
/*
|
|
151
|
-
Assign our forwarded ref to a wrapper element.
|
|
152
|
-
Ideally, this should be assigned to the textarea inside <ReactMde /> component.
|
|
153
|
-
Whilst `react-mde` does allow you to target individual sub-components' refs,
|
|
154
|
-
it will complain if you try and assign a forwarded ref.
|
|
155
|
-
*/ return /*#__PURE__*/ (0, $jPEKE$jsx)("div", {
|
|
53
|
+
/* const saveImage = async function* (data: any) {
|
|
54
|
+
|
|
55
|
+
let success = true
|
|
56
|
+
const result = await client.assets
|
|
57
|
+
.upload('image', data)
|
|
58
|
+
.then((doc) => `${doc.url}?w=450`)
|
|
59
|
+
.catch(() => {
|
|
60
|
+
success = false
|
|
61
|
+
return `Error: Could not upload file. Only images are supported.`
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
yield result
|
|
65
|
+
return success
|
|
66
|
+
}*/ const { sanity: studioTheme } = (0, $jPEKE$useTheme)();
|
|
67
|
+
return /*#__PURE__*/ (0, $jPEKE$jsx)("div", {
|
|
156
68
|
ref: ref,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
textArea: {
|
|
169
|
-
id: inputId,
|
|
170
|
-
onBlur: onBlur,
|
|
171
|
-
onFocus: onFocus
|
|
172
|
-
},
|
|
173
|
-
writeButton: {
|
|
174
|
-
tabIndex: -1
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
paste: {
|
|
178
|
-
saveImage: saveImage
|
|
179
|
-
},
|
|
180
|
-
refs: {
|
|
181
|
-
textarea: textarea
|
|
182
|
-
}
|
|
69
|
+
"data-color-mode": studioTheme.color.dark ? "dark" : "light",
|
|
70
|
+
children: readOnly ? /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Card), {
|
|
71
|
+
border: true,
|
|
72
|
+
padding: 3,
|
|
73
|
+
children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$uiwreactmdeditor).Markdown, {
|
|
74
|
+
source: value,
|
|
75
|
+
rehypePlugins: [
|
|
76
|
+
[
|
|
77
|
+
(0, $jPEKE$rehypesanitize)
|
|
78
|
+
]
|
|
79
|
+
]
|
|
183
80
|
})
|
|
81
|
+
}) : /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$uiwreactmdeditor), {
|
|
82
|
+
value: editedValue,
|
|
83
|
+
onChange: setEditedValue,
|
|
84
|
+
onBlur: onBlur,
|
|
85
|
+
onFocus: onFocus,
|
|
86
|
+
previewOptions: {
|
|
87
|
+
rehypePlugins: [
|
|
88
|
+
[
|
|
89
|
+
(0, $jPEKE$rehypesanitize)
|
|
90
|
+
]
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
preview: "edit"
|
|
184
94
|
})
|
|
185
95
|
});
|
|
186
96
|
});
|
|
187
97
|
|
|
188
98
|
|
|
189
99
|
|
|
100
|
+
// re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:
|
|
101
|
+
const $df9eabe9bda49ea8$export$18a9461578883ec4 = (0, $483dd42bf797352b$export$18a9461578883ec4);
|
|
190
102
|
const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
|
|
191
103
|
name: "markdown-editor",
|
|
192
104
|
schema: {
|
|
@@ -196,7 +108,7 @@ const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
|
|
|
196
108
|
name: "markdown",
|
|
197
109
|
title: "Markdown",
|
|
198
110
|
components: {
|
|
199
|
-
input:
|
|
111
|
+
input: $df9eabe9bda49ea8$export$18a9461578883ec4
|
|
200
112
|
}
|
|
201
113
|
}),
|
|
202
114
|
]
|
|
@@ -204,5 +116,5 @@ const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
|
|
|
204
116
|
});
|
|
205
117
|
|
|
206
118
|
|
|
207
|
-
export {$df9eabe9bda49ea8$export$
|
|
119
|
+
export {$df9eabe9bda49ea8$export$18a9461578883ec4 as MarkdownEditor, $df9eabe9bda49ea8$export$f225414958dd8925 as markdownSchema};
|
|
208
120
|
//# sourceMappingURL=index.modern.js.map
|
package/lib/index.modern.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["src/index.ts","src/components/Editor.tsx","src/hooks/useDebounce.ts"],"sourcesContent":["import {MarkdownEditor} from './components/Editor'\nimport {createPlugin, defineType} from 'sanity'\n\nexport {MarkdownEditor}\n\nexport const markdownSchema = createPlugin({\n name: 'markdown-editor',\n schema: {\n types: [\n defineType({\n type: 'string',\n name: 'markdown',\n title: 'Markdown',\n components: {\n input: MarkdownEditor,\n },\n }),\n ],\n },\n})\n","import ReactMde from 'react-mde'\nimport ReactMarkdown from 'react-markdown'\nimport gfm from 'remark-gfm'\nimport {useId} from '@reach/auto-id'\n\nimport useDebounce from '../hooks/useDebounce'\nimport 'react-mde/lib/styles/css/react-mde-all.css'\nimport {PatchEvent, set, unset} from 'sanity/form'\nimport {StringInputProps, useClient} from 'sanity'\nimport React, {\n FC,\n forwardRef,\n PropsWithChildren,\n Ref,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {ToolbarCommands} from 'react-mde/lib/definitions/types'\nimport styled from 'styled-components'\nimport {Theme, useTheme} from '@sanity/ui'\n\nconst Preview = ({markdown}: {markdown: string}) => {\n return <ReactMarkdown plugins={[gfm]}>{markdown}</ReactMarkdown>\n}\n\nconst defaultToolbarCommands = [\n ['header', 'bold', 'italic', 'strikethrough'],\n ['link', 'quote', 'code'],\n ['unordered-list', 'ordered-list', 'checked-list'],\n]\n\ntype SanityTheme = Theme['sanity']\n\ntype Style = PropsWithChildren<{\n studioTheme: SanityTheme\n}>\n\n// !important is used whenever we need to override inline styles for an element\nconst MarkdownTheme: FC<Style> = styled.div`\n & .react-mde {\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n }\n\n & .mde-text {\n background: ${({studioTheme}: Style) => studioTheme.color.input.default.enabled.bg} !important;\n color: ${({studioTheme}: Style) => studioTheme.color.input.default.enabled.fg} !important;\n }\n\n & .mde-header {\n background: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg};\n color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.fg};\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n\n & button,\n .mde-header-item.mde-header-item.mde-header-item button {\n color: ${({studioTheme}: Style) => studioTheme.color.button.bleed.default.enabled.fg};\n }\n\n & button.selected {\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n }\n }\n\n & .image-tip {\n background: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg};\n color: ${({studioTheme}: Style) => studioTheme.color.muted.default.enabled.fg};\n font-family: ${({studioTheme}: Style) => studioTheme.fonts.text.family};\n border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};\n }\n`\n\nexport const MarkdownEditor = forwardRef(function MarkdownEditor(\n props: StringInputProps,\n ref: Ref<any>\n) {\n const {schemaType: type, value = '', onBlur, onChange, onFocus, readOnly} = props\n const options: {toolbar?: ToolbarCommands} | undefined = type.options as any\n const [selectedTab, setSelectedTab] = useState<'write' | 'preview'>('write')\n const [editedValue, setEditedValue] = useState(value)\n const debouncedValue = useDebounce(editedValue, 100)\n const textarea = useRef<HTMLTextAreaElement>(null)\n const sanityClient = useClient()\n\n // Conditionally update textarea styles based on read only access.\n // It's also possible to define inline styles via `childProps.textArea.style` on `<ReactMde />`,\n // but this will override any dynamically created styles provided by the component itself.\n useEffect(() => {\n if (textarea.current) {\n textarea.current.style.backgroundColor = readOnly ? 'rgba(240,240,240)' : 'rgba(255,255,255)'\n }\n }, [textarea, readOnly])\n\n useEffect(() => {\n setEditedValue(value)\n }, [value])\n\n useEffect(() => {\n if (!debouncedValue && value) {\n onChange(PatchEvent.from([unset()]))\n } else if (debouncedValue !== value) {\n onChange(PatchEvent.from([set(debouncedValue)]))\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedValue, onChange])\n\n const saveImage = async function* (data: any) {\n const client = sanityClient.withConfig({apiVersion: '2021-03-25'})\n\n let success = true\n const result = await client.assets\n .upload('image', data)\n .then((doc) => `${doc.url}?w=450`)\n .catch(() => {\n success = false\n return `Error: Could not upload file. Only images are supported.`\n })\n\n yield result\n return success\n }\n\n const generatePreview = useCallback(\n (markdown: string) => Promise.resolve(<Preview markdown={markdown} />),\n []\n )\n\n const inputId = useId()\n const {sanity: studioTheme} = useTheme()\n /*\n Assign our forwarded ref to a wrapper element.\n Ideally, this should be assigned to the textarea inside <ReactMde /> component.\n Whilst `react-mde` does allow you to target individual sub-components' refs,\n it will complain if you try and assign a forwarded ref.\n */\n return (\n <div ref={ref}>\n <MarkdownTheme studioTheme={studioTheme}>\n <ReactMde\n toolbarCommands={options?.toolbar || defaultToolbarCommands}\n value={editedValue}\n onChange={setEditedValue}\n selectedTab={selectedTab}\n onTabChange={setSelectedTab}\n readOnly={readOnly}\n generateMarkdownPreview={generatePreview}\n childProps={{\n textArea: {\n id: inputId,\n onBlur,\n onFocus,\n },\n writeButton: {\n tabIndex: -1,\n },\n }}\n paste={{saveImage}}\n refs={{textarea}}\n />\n </MarkdownTheme>\n </div>\n )\n})\n","import {useState, useEffect} from 'react'\n\nexport default function useDebounce(value: unknown, delay: number) {\n const [debouncedValue, setDebouncedValue] = useState(value)\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value)\n }, delay)\n\n return () => clearTimeout(handler)\n }, [value, delay])\n\n return debouncedValue\n}\n"],"names":[],"version":3,"file":"index.modern.js.map","sourceRoot":"../"}
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts","src/components/Editor.tsx","src/hooks/useDebounce.ts"],"sourcesContent":["import {MarkdownEditor as Editor} from './components/Editor'\nimport {createPlugin, defineType} from 'sanity'\n\n// re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:\nconst MarkdownEditor = Editor\n\nexport {MarkdownEditor}\n\nexport const markdownSchema = createPlugin({\n name: 'markdown-editor',\n schema: {\n types: [\n defineType({\n type: 'string' as const,\n name: 'markdown',\n title: 'Markdown',\n components: {\n input: MarkdownEditor,\n },\n }),\n ],\n },\n})\n","import MDEditor from '@uiw/react-md-editor'\nimport useDebounce from '../hooks/useDebounce'\nimport {PatchEvent, set, unset} from 'sanity/form'\nimport {StringInputProps} from 'sanity'\nimport React, {forwardRef, Ref, useEffect, useState} from 'react'\nimport {Card, useTheme} from '@sanity/ui'\nimport rehypeSanitize from 'rehype-sanitize'\n\nexport const MarkdownEditor = forwardRef(function MarkdownEditor(\n props: StringInputProps,\n ref: Ref<any>\n) {\n const {\n value = '',\n onChange,\n elementProps: {onBlur, onFocus},\n readOnly,\n } = props\n const [editedValue, setEditedValue] = useState<string | undefined>(value)\n const debouncedValue = useDebounce(editedValue, 100)\n // const client = useClient({apiVersion: '2021-03-25'})\n\n useEffect(() => {\n setEditedValue(value)\n }, [value])\n\n useEffect(() => {\n if (!debouncedValue && value) {\n onChange(PatchEvent.from([unset()]))\n } else if (debouncedValue !== value) {\n onChange(PatchEvent.from([set(debouncedValue)]))\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedValue, onChange])\n\n /* const saveImage = async function* (data: any) {\n\n let success = true\n const result = await client.assets\n .upload('image', data)\n .then((doc) => `${doc.url}?w=450`)\n .catch(() => {\n success = false\n return `Error: Could not upload file. Only images are supported.`\n })\n\n yield result\n return success\n }*/\n\n const {sanity: studioTheme} = useTheme()\n return (\n <div ref={ref} data-color-mode={studioTheme.color.dark ? 'dark' : 'light'}>\n {readOnly ? (\n <Card border padding={3}>\n <MDEditor.Markdown source={value} rehypePlugins={[[rehypeSanitize]]} />\n </Card>\n ) : (\n <MDEditor\n value={editedValue}\n onChange={setEditedValue}\n onBlur={onBlur}\n onFocus={onFocus}\n previewOptions={{\n rehypePlugins: [[rehypeSanitize]],\n }}\n preview=\"edit\"\n />\n )}\n </div>\n )\n})\n","import {useState, useEffect} from 'react'\n\nexport default function useDebounce(value: unknown, delay: number) {\n const [debouncedValue, setDebouncedValue] = useState(value)\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value)\n }, delay)\n\n return () => clearTimeout(handler)\n }, [value, delay])\n\n return debouncedValue\n}\n"],"names":[],"version":3,"file":"index.modern.js.map","sourceRoot":"../"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-markdown",
|
|
3
|
-
"version": "3.0.0-v3-studio.
|
|
3
|
+
"version": "3.0.0-v3-studio.2",
|
|
4
4
|
"description": "Markdown fields in Sanity Studio. Supports Github flavored Markdown and image uploads.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"clean": "rimraf lib",
|
|
@@ -39,18 +39,18 @@
|
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@reach/auto-id": "^0.17.0",
|
|
42
|
-
"@sanity/incompatible-plugin": "^
|
|
43
|
-
"@sanity/ui": "^0.
|
|
44
|
-
"react-
|
|
45
|
-
"
|
|
46
|
-
"remark-gfm": "^1.0.0"
|
|
42
|
+
"@sanity/incompatible-plugin": "^1.0.1",
|
|
43
|
+
"@sanity/ui": "^0.38.0",
|
|
44
|
+
"@uiw/react-md-editor": "^3.18.1",
|
|
45
|
+
"rehype-sanitize": "^5.0.1"
|
|
47
46
|
},
|
|
48
47
|
"devDependencies": {
|
|
49
|
-
"@commitlint/cli": "^
|
|
50
|
-
"@commitlint/config-conventional": "^
|
|
51
|
-
"@parcel/packager-ts": "^2.
|
|
52
|
-
"@parcel/transformer-typescript-types": "^2.
|
|
53
|
-
"@sanity/plugin-kit": "^
|
|
48
|
+
"@commitlint/cli": "^17.1.2",
|
|
49
|
+
"@commitlint/config-conventional": "^17.1.0",
|
|
50
|
+
"@parcel/packager-ts": "^2.7.0",
|
|
51
|
+
"@parcel/transformer-typescript-types": "^2.7.0",
|
|
52
|
+
"@sanity/plugin-kit": "^1.1.0-ecosystem-preset.5",
|
|
53
|
+
"@sanity/semantic-release-preset": "^2.0.1",
|
|
54
54
|
"@types/styled-components": "^5.1.25",
|
|
55
55
|
"@typescript-eslint/eslint-plugin": "^5.12.0",
|
|
56
56
|
"@typescript-eslint/parser": "^5.12.0",
|
|
@@ -60,15 +60,15 @@
|
|
|
60
60
|
"eslint-plugin-prettier": "4.0.0",
|
|
61
61
|
"eslint-plugin-react": "^7.28.0",
|
|
62
62
|
"eslint-plugin-react-hooks": "^4.5.0",
|
|
63
|
-
"husky": "^
|
|
64
|
-
"lint-staged": "^
|
|
65
|
-
"parcel": "^2.
|
|
63
|
+
"husky": "^8.0.1",
|
|
64
|
+
"lint-staged": "^13.0.3",
|
|
65
|
+
"parcel": "^2.7.0",
|
|
66
66
|
"prettier": "^2.5.1",
|
|
67
67
|
"react": "^17.0.0 || ^18.0.0",
|
|
68
68
|
"rimraf": "^3.0.2",
|
|
69
|
-
"sanity": "
|
|
69
|
+
"sanity": "3.0.0-dev-preview.17",
|
|
70
70
|
"styled-components": "^5.2.0",
|
|
71
|
-
"typescript": "
|
|
71
|
+
"typescript": "4.7.4"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"react": "^17.0.0 || ^18.0.0",
|
|
@@ -1,96 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
import ReactMarkdown from 'react-markdown'
|
|
3
|
-
import gfm from 'remark-gfm'
|
|
4
|
-
import {useId} from '@reach/auto-id'
|
|
5
|
-
|
|
1
|
+
import MDEditor from '@uiw/react-md-editor'
|
|
6
2
|
import useDebounce from '../hooks/useDebounce'
|
|
7
|
-
import 'react-mde/lib/styles/css/react-mde-all.css'
|
|
8
3
|
import {PatchEvent, set, unset} from 'sanity/form'
|
|
9
|
-
import {StringInputProps
|
|
10
|
-
import React, {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
PropsWithChildren,
|
|
14
|
-
Ref,
|
|
15
|
-
useCallback,
|
|
16
|
-
useEffect,
|
|
17
|
-
useRef,
|
|
18
|
-
useState,
|
|
19
|
-
} from 'react'
|
|
20
|
-
import {ToolbarCommands} from 'react-mde/lib/definitions/types'
|
|
21
|
-
import styled from 'styled-components'
|
|
22
|
-
import {Theme, useTheme} from '@sanity/ui'
|
|
23
|
-
|
|
24
|
-
const Preview = ({markdown}: {markdown: string}) => {
|
|
25
|
-
return <ReactMarkdown plugins={[gfm]}>{markdown}</ReactMarkdown>
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const defaultToolbarCommands = [
|
|
29
|
-
['header', 'bold', 'italic', 'strikethrough'],
|
|
30
|
-
['link', 'quote', 'code'],
|
|
31
|
-
['unordered-list', 'ordered-list', 'checked-list'],
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
type SanityTheme = Theme['sanity']
|
|
35
|
-
|
|
36
|
-
type Style = PropsWithChildren<{
|
|
37
|
-
studioTheme: SanityTheme
|
|
38
|
-
}>
|
|
39
|
-
|
|
40
|
-
// !important is used whenever we need to override inline styles for an element
|
|
41
|
-
const MarkdownTheme: FC<Style> = styled.div`
|
|
42
|
-
& .react-mde {
|
|
43
|
-
border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
& .mde-text {
|
|
47
|
-
background: ${({studioTheme}: Style) => studioTheme.color.input.default.enabled.bg} !important;
|
|
48
|
-
color: ${({studioTheme}: Style) => studioTheme.color.input.default.enabled.fg} !important;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
& .mde-header {
|
|
52
|
-
background: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg};
|
|
53
|
-
color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.fg};
|
|
54
|
-
border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};
|
|
55
|
-
|
|
56
|
-
& button,
|
|
57
|
-
.mde-header-item.mde-header-item.mde-header-item button {
|
|
58
|
-
color: ${({studioTheme}: Style) => studioTheme.color.button.bleed.default.enabled.fg};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
& button.selected {
|
|
62
|
-
border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
& .image-tip {
|
|
67
|
-
background: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg};
|
|
68
|
-
color: ${({studioTheme}: Style) => studioTheme.color.muted.default.enabled.fg};
|
|
69
|
-
font-family: ${({studioTheme}: Style) => studioTheme.fonts.text.family};
|
|
70
|
-
border-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.border};
|
|
71
|
-
}
|
|
72
|
-
`
|
|
4
|
+
import {StringInputProps} from 'sanity'
|
|
5
|
+
import React, {forwardRef, Ref, useEffect, useState} from 'react'
|
|
6
|
+
import {Card, useTheme} from '@sanity/ui'
|
|
7
|
+
import rehypeSanitize from 'rehype-sanitize'
|
|
73
8
|
|
|
74
9
|
export const MarkdownEditor = forwardRef(function MarkdownEditor(
|
|
75
10
|
props: StringInputProps,
|
|
76
11
|
ref: Ref<any>
|
|
77
12
|
) {
|
|
78
|
-
const {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
13
|
+
const {
|
|
14
|
+
value = '',
|
|
15
|
+
onChange,
|
|
16
|
+
elementProps: {onBlur, onFocus},
|
|
17
|
+
readOnly,
|
|
18
|
+
} = props
|
|
19
|
+
const [editedValue, setEditedValue] = useState<string | undefined>(value)
|
|
82
20
|
const debouncedValue = useDebounce(editedValue, 100)
|
|
83
|
-
const
|
|
84
|
-
const sanityClient = useClient()
|
|
85
|
-
|
|
86
|
-
// Conditionally update textarea styles based on read only access.
|
|
87
|
-
// It's also possible to define inline styles via `childProps.textArea.style` on `<ReactMde />`,
|
|
88
|
-
// but this will override any dynamically created styles provided by the component itself.
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
if (textarea.current) {
|
|
91
|
-
textarea.current.style.backgroundColor = readOnly ? 'rgba(240,240,240)' : 'rgba(255,255,255)'
|
|
92
|
-
}
|
|
93
|
-
}, [textarea, readOnly])
|
|
21
|
+
// const client = useClient({apiVersion: '2021-03-25'})
|
|
94
22
|
|
|
95
23
|
useEffect(() => {
|
|
96
24
|
setEditedValue(value)
|
|
@@ -105,8 +33,7 @@ export const MarkdownEditor = forwardRef(function MarkdownEditor(
|
|
|
105
33
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
106
34
|
}, [debouncedValue, onChange])
|
|
107
35
|
|
|
108
|
-
const saveImage = async function* (data: any) {
|
|
109
|
-
const client = sanityClient.withConfig({apiVersion: '2021-03-25'})
|
|
36
|
+
/* const saveImage = async function* (data: any) {
|
|
110
37
|
|
|
111
38
|
let success = true
|
|
112
39
|
const result = await client.assets
|
|
@@ -119,46 +46,27 @@ export const MarkdownEditor = forwardRef(function MarkdownEditor(
|
|
|
119
46
|
|
|
120
47
|
yield result
|
|
121
48
|
return success
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const generatePreview = useCallback(
|
|
125
|
-
(markdown: string) => Promise.resolve(<Preview markdown={markdown} />),
|
|
126
|
-
[]
|
|
127
|
-
)
|
|
49
|
+
}*/
|
|
128
50
|
|
|
129
|
-
const inputId = useId()
|
|
130
51
|
const {sanity: studioTheme} = useTheme()
|
|
131
|
-
/*
|
|
132
|
-
Assign our forwarded ref to a wrapper element.
|
|
133
|
-
Ideally, this should be assigned to the textarea inside <ReactMde /> component.
|
|
134
|
-
Whilst `react-mde` does allow you to target individual sub-components' refs,
|
|
135
|
-
it will complain if you try and assign a forwarded ref.
|
|
136
|
-
*/
|
|
137
52
|
return (
|
|
138
|
-
<div ref={ref}>
|
|
139
|
-
|
|
140
|
-
<
|
|
141
|
-
|
|
53
|
+
<div ref={ref} data-color-mode={studioTheme.color.dark ? 'dark' : 'light'}>
|
|
54
|
+
{readOnly ? (
|
|
55
|
+
<Card border padding={3}>
|
|
56
|
+
<MDEditor.Markdown source={value} rehypePlugins={[[rehypeSanitize]]} />
|
|
57
|
+
</Card>
|
|
58
|
+
) : (
|
|
59
|
+
<MDEditor
|
|
142
60
|
value={editedValue}
|
|
143
61
|
onChange={setEditedValue}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
childProps={{
|
|
149
|
-
textArea: {
|
|
150
|
-
id: inputId,
|
|
151
|
-
onBlur,
|
|
152
|
-
onFocus,
|
|
153
|
-
},
|
|
154
|
-
writeButton: {
|
|
155
|
-
tabIndex: -1,
|
|
156
|
-
},
|
|
62
|
+
onBlur={onBlur}
|
|
63
|
+
onFocus={onFocus}
|
|
64
|
+
previewOptions={{
|
|
65
|
+
rehypePlugins: [[rehypeSanitize]],
|
|
157
66
|
}}
|
|
158
|
-
|
|
159
|
-
refs={{textarea}}
|
|
67
|
+
preview="edit"
|
|
160
68
|
/>
|
|
161
|
-
|
|
69
|
+
)}
|
|
162
70
|
</div>
|
|
163
71
|
)
|
|
164
72
|
})
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {MarkdownEditor} from './components/Editor'
|
|
1
|
+
import {MarkdownEditor as Editor} from './components/Editor'
|
|
2
2
|
import {createPlugin, defineType} from 'sanity'
|
|
3
3
|
|
|
4
|
+
// re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:
|
|
5
|
+
const MarkdownEditor = Editor
|
|
6
|
+
|
|
4
7
|
export {MarkdownEditor}
|
|
5
8
|
|
|
6
9
|
export const markdownSchema = createPlugin({
|
|
@@ -8,7 +11,7 @@ export const markdownSchema = createPlugin({
|
|
|
8
11
|
schema: {
|
|
9
12
|
types: [
|
|
10
13
|
defineType({
|
|
11
|
-
type: 'string',
|
|
14
|
+
type: 'string' as const,
|
|
12
15
|
name: 'markdown',
|
|
13
16
|
title: 'Markdown',
|
|
14
17
|
components: {
|