sanity-plugin-markdown 2.1.1 → 3.0.0-v3-studio.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/README.md CHANGED
@@ -1,14 +1,47 @@
1
1
  # sanity-plugin-markdown
2
- A Markdown editor with preview for Sanity Studio. 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. The inserted image(s) has a default width crop in the url which you can change to your liking with the [Sanity image pipeline parameters](https://www.sanity.io/docs/image-urls).
2
+
3
+ > **NOTE**
4
+ >
5
+ > This is the **Sanity Studio v3 version** of sanity-plugin-markdown.
6
+ >
7
+ > For the v2 version, please refer to the [v2-branch](https://github.com/sanity-io/sanity-plugin-markdown).
8
+
9
+ ## What is it?
10
+
11
+ A Markdown editor with preview for Sanity Studio.
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. 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).
14
+
15
+ ![Markdown input](assets/markdown-input.png)
3
16
 
4
17
  ## Installation
5
18
 
6
19
  ```
7
- sanity install markdown
20
+ npm install --save sanity-plugin-markdown@studio-v3
21
+ ```
22
+
23
+ or
24
+
25
+ ```
26
+ yarn add sanity-plugin-markdown@studio-v3
8
27
  ```
9
28
 
10
29
  ## Usage
11
- Declare a field in your schema to be `markdown`
30
+
31
+ Add it as a plugin in sanity.config.ts (or .js):
32
+
33
+ ```js
34
+ import { markdownSchema } from "sanity-plugin-markdown";
35
+
36
+ export default createConfig({
37
+ // ...
38
+ plugins: [
39
+ markdownSchema(),
40
+ ]
41
+ })
42
+ ```
43
+
44
+ Then, declare a field in your schema to be `markdown`
12
45
 
13
46
  ```javascript
14
47
  const myDocument = {
@@ -32,3 +65,25 @@ const myDocument = {
32
65
 
33
66
  MIT © Sanity.io
34
67
  See LICENSE
68
+
69
+ ## Develop & test
70
+
71
+ Make sure to run `npm run build` once, then run
72
+
73
+ ```bash
74
+ npm run link-watch
75
+ ```
76
+
77
+ In another shell, `cd` to your test studio and run:
78
+
79
+ ```bash
80
+ npx yalc add sanity-plugin-markdown --link && yarn install
81
+ ```
82
+
83
+ Now, changes in this repo will be automatically built and pushed to the studio,
84
+ triggering hotreload. Yalc avoids issues with react-hooks that are typical when using yarn/npm link.
85
+
86
+ ### About build & watch
87
+
88
+ This plugin uses [@sanity/plugin-sdk](https://github.com/sanity-io/plugin-sdk)
89
+ with default configuration for build & watch scripts.
package/lib/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { StringInputProps } from "sanity";
2
+ import React from "react";
3
+ export const MarkdownEditor: React.ForwardRefExoticComponent<StringInputProps<import("sanity").StringSchemaType> & React.RefAttributes<any>>;
4
+ export const markdownSchema: import("sanity").Plugin<void>;
5
+
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"mappings":";;ACyEA,OAAO,MAAM,+HA0FX,CAAA;AC9JF,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} 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"],"names":[],"version":3,"file":"index.d.ts.map","sourceRoot":"../"}
package/lib/index.js ADDED
@@ -0,0 +1,216 @@
1
+ var $3KLdq$sanity = require("sanity");
2
+ var $3KLdq$reactjsxruntime = require("react/jsx-runtime");
3
+ var $3KLdq$reactmde = require("react-mde");
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");
8
+ var $3KLdq$sanityform = require("sanity/form");
9
+ var $3KLdq$react = require("react");
10
+ var $3KLdq$styledcomponents = require("styled-components");
11
+ var $3KLdq$sanityui = require("@sanity/ui");
12
+
13
+ function $parcel$export(e, n, v, s) {
14
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
15
+ }
16
+ function $parcel$interopDefault(a) {
17
+ return a && a.__esModule ? a.default : a;
18
+ }
19
+
20
+ $parcel$export(module.exports, "markdownSchema", () => $244e63ca53592e4d$export$f225414958dd8925);
21
+ $parcel$export(module.exports, "MarkdownEditor", () => $067e75d167fd097d$export$18a9461578883ec4);
22
+
23
+
24
+
25
+
26
+
27
+
28
+ function $84fd43422be26bd7$export$2e2bcd8739ae039(value, delay) {
29
+ const [debouncedValue, setDebouncedValue] = (0, $3KLdq$react.useState)(value);
30
+ (0, $3KLdq$react.useEffect)(()=>{
31
+ const handler = setTimeout(()=>{
32
+ setDebouncedValue(value);
33
+ }, delay);
34
+ return ()=>clearTimeout(handler);
35
+ }, [
36
+ value,
37
+ delay
38
+ ]);
39
+ return debouncedValue;
40
+ }
41
+
42
+
43
+
44
+
45
+
46
+
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
+ const $067e75d167fd097d$export$18a9461578883ec4 = /*#__PURE__*/ (0, $3KLdq$react.forwardRef)(function MarkdownEditor(props, ref) {
109
+ const { schemaType: type , value: value = "" , onBlur: onBlur , onChange: onChange , onFocus: onFocus , readOnly: readOnly } = props;
110
+ const options = type.options;
111
+ const [selectedTab, setSelectedTab] = (0, $3KLdq$react.useState)("write");
112
+ const [editedValue, setEditedValue] = (0, $3KLdq$react.useState)(value);
113
+ const debouncedValue = (0, $84fd43422be26bd7$export$2e2bcd8739ae039)(editedValue, 100);
114
+ const textarea = (0, $3KLdq$react.useRef)(null);
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
+ ]);
125
+ (0, $3KLdq$react.useEffect)(()=>{
126
+ setEditedValue(value);
127
+ }, [
128
+ value
129
+ ]);
130
+ (0, $3KLdq$react.useEffect)(()=>{
131
+ if (!debouncedValue && value) onChange((0, $3KLdq$sanityform.PatchEvent).from([
132
+ (0, $3KLdq$sanityform.unset)()
133
+ ]));
134
+ else if (debouncedValue !== value) onChange((0, $3KLdq$sanityform.PatchEvent).from([
135
+ (0, $3KLdq$sanityform.set)(debouncedValue)
136
+ ]));
137
+ // eslint-disable-next-line react-hooks/exhaustive-deps
138
+ }, [
139
+ debouncedValue,
140
+ onChange
141
+ ]);
142
+ const saveImage = async function*(data) {
143
+ const client = sanityClient.withConfig({
144
+ apiVersion: "2021-03-25"
145
+ });
146
+ let success = true;
147
+ const result = await client.assets.upload("image", data).then((doc)=>`${doc.url}?w=450`).catch(()=>{
148
+ success = false;
149
+ return `Error: Could not upload file. Only images are supported.`;
150
+ });
151
+ yield result;
152
+ return success;
153
+ };
154
+ const generatePreview = (0, $3KLdq$react.useCallback)((markdown)=>Promise.resolve(/*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)($067e75d167fd097d$var$Preview, {
155
+ markdown: markdown
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", {
165
+ ref: ref,
166
+ children: /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)($067e75d167fd097d$var$MarkdownTheme, {
167
+ studioTheme: studioTheme,
168
+ children: /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, ($parcel$interopDefault($3KLdq$reactmde))), {
169
+ toolbarCommands: options?.toolbar || $067e75d167fd097d$var$defaultToolbarCommands,
170
+ value: editedValue,
171
+ onChange: setEditedValue,
172
+ selectedTab: selectedTab,
173
+ onTabChange: setSelectedTab,
174
+ readOnly: readOnly,
175
+ generateMarkdownPreview: generatePreview,
176
+ childProps: {
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
+ }
192
+ })
193
+ })
194
+ });
195
+ });
196
+
197
+
198
+
199
+ const $244e63ca53592e4d$export$f225414958dd8925 = (0, $3KLdq$sanity.createPlugin)({
200
+ name: "markdown-editor",
201
+ schema: {
202
+ types: [
203
+ (0, $3KLdq$sanity.defineType)({
204
+ type: "string",
205
+ name: "markdown",
206
+ title: "Markdown",
207
+ components: {
208
+ input: (0, $067e75d167fd097d$export$18a9461578883ec4)
209
+ }
210
+ }),
211
+ ]
212
+ }
213
+ });
214
+
215
+
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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":"../"}
@@ -0,0 +1,208 @@
1
+ import {createPlugin as $jPEKE$createPlugin, defineType as $jPEKE$defineType, useClient as $jPEKE$useClient} from "sanity";
2
+ import {jsx as $jPEKE$jsx} from "react/jsx-runtime";
3
+ import $jPEKE$reactmde from "react-mde";
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";
8
+ 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, useRef as $jPEKE$useRef, useEffect as $jPEKE$useEffect, useCallback as $jPEKE$useCallback} from "react";
10
+ import $jPEKE$styledcomponents from "styled-components";
11
+ import {useTheme as $jPEKE$useTheme} from "@sanity/ui";
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+ function $a9f5cf746146e5f0$export$2e2bcd8739ae039(value, delay) {
20
+ const [debouncedValue, setDebouncedValue] = (0, $jPEKE$useState)(value);
21
+ (0, $jPEKE$useEffect)(()=>{
22
+ const handler = setTimeout(()=>{
23
+ setDebouncedValue(value);
24
+ }, delay);
25
+ return ()=>clearTimeout(handler);
26
+ }, [
27
+ value,
28
+ delay
29
+ ]);
30
+ return debouncedValue;
31
+ }
32
+
33
+
34
+
35
+
36
+
37
+
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
+ const $483dd42bf797352b$export$18a9461578883ec4 = /*#__PURE__*/ (0, $jPEKE$forwardRef)(function MarkdownEditor(props, ref) {
100
+ const { schemaType: type , value: value = "" , onBlur: onBlur , onChange: onChange , onFocus: onFocus , readOnly: readOnly } = props;
101
+ const options = type.options;
102
+ const [selectedTab, setSelectedTab] = (0, $jPEKE$useState)("write");
103
+ const [editedValue, setEditedValue] = (0, $jPEKE$useState)(value);
104
+ const debouncedValue = (0, $a9f5cf746146e5f0$export$2e2bcd8739ae039)(editedValue, 100);
105
+ const textarea = (0, $jPEKE$useRef)(null);
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
+ ]);
116
+ (0, $jPEKE$useEffect)(()=>{
117
+ setEditedValue(value);
118
+ }, [
119
+ value
120
+ ]);
121
+ (0, $jPEKE$useEffect)(()=>{
122
+ if (!debouncedValue && value) onChange((0, $jPEKE$PatchEvent).from([
123
+ (0, $jPEKE$unset)()
124
+ ]));
125
+ else if (debouncedValue !== value) onChange((0, $jPEKE$PatchEvent).from([
126
+ (0, $jPEKE$set)(debouncedValue)
127
+ ]));
128
+ // eslint-disable-next-line react-hooks/exhaustive-deps
129
+ }, [
130
+ debouncedValue,
131
+ onChange
132
+ ]);
133
+ const saveImage = async function*(data) {
134
+ const client = sanityClient.withConfig({
135
+ apiVersion: "2021-03-25"
136
+ });
137
+ let success = true;
138
+ const result = await client.assets.upload("image", data).then((doc)=>`${doc.url}?w=450`).catch(()=>{
139
+ success = false;
140
+ return `Error: Could not upload file. Only images are supported.`;
141
+ });
142
+ yield result;
143
+ return success;
144
+ };
145
+ const generatePreview = (0, $jPEKE$useCallback)((markdown)=>Promise.resolve(/*#__PURE__*/ (0, $jPEKE$jsx)($483dd42bf797352b$var$Preview, {
146
+ markdown: markdown
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", {
156
+ ref: ref,
157
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)($483dd42bf797352b$var$MarkdownTheme, {
158
+ studioTheme: studioTheme,
159
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$reactmde), {
160
+ toolbarCommands: options?.toolbar || $483dd42bf797352b$var$defaultToolbarCommands,
161
+ value: editedValue,
162
+ onChange: setEditedValue,
163
+ selectedTab: selectedTab,
164
+ onTabChange: setSelectedTab,
165
+ readOnly: readOnly,
166
+ generateMarkdownPreview: generatePreview,
167
+ childProps: {
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
+ }
183
+ })
184
+ })
185
+ });
186
+ });
187
+
188
+
189
+
190
+ const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
191
+ name: "markdown-editor",
192
+ schema: {
193
+ types: [
194
+ (0, $jPEKE$defineType)({
195
+ type: "string",
196
+ name: "markdown",
197
+ title: "Markdown",
198
+ components: {
199
+ input: (0, $483dd42bf797352b$export$18a9461578883ec4)
200
+ }
201
+ }),
202
+ ]
203
+ }
204
+ });
205
+
206
+
207
+ export {$df9eabe9bda49ea8$export$f225414958dd8925 as markdownSchema, $483dd42bf797352b$export$18a9461578883ec4 as MarkdownEditor};
208
+ //# sourceMappingURL=index.modern.js.map
@@ -0,0 +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":"../"}
package/package.json CHANGED
@@ -1,12 +1,33 @@
1
1
  {
2
2
  "name": "sanity-plugin-markdown",
3
- "version": "2.1.1",
3
+ "version": "3.0.0-v3-studio.0",
4
4
  "description": "Markdown fields in Sanity Studio. Supports Github flavored Markdown and image uploads.",
5
5
  "scripts": {
6
- "build": "sanipack build",
7
- "watch": "sanipack build --watch",
8
- "prepublishOnly": "sanipack build"
6
+ "clean": "rimraf lib",
7
+ "prebuild": "npm run clean && plugin-kit verify-package --silent",
8
+ "build": "parcel build --no-cache",
9
+ "watch": "parcel watch",
10
+ "link-watch": "plugin-kit link-watch",
11
+ "lint": "eslint .",
12
+ "format": "prettier src -w",
13
+ "prepare": "husky install",
14
+ "compile": "tsc --noEmit",
15
+ "prepublishOnly": " npm run build"
9
16
  },
17
+ "source": "./src/index.ts",
18
+ "main": "./lib/index.js",
19
+ "module": "./lib/index.modern.js",
20
+ "types": "./lib/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "require": "./lib/index.js",
24
+ "default": "./lib/index.modern.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "src",
29
+ "lib"
30
+ ],
10
31
  "keywords": [
11
32
  "sanity",
12
33
  "sanity-plugin",
@@ -17,37 +38,42 @@
17
38
  "author": "Sanity.io <hello@sanity.io>",
18
39
  "license": "MIT",
19
40
  "dependencies": {
20
- "@reach/auto-id": "^0.13.2",
41
+ "@reach/auto-id": "^0.17.0",
42
+ "@sanity/incompatible-plugin": "^0.0.1-studio-v3.3",
43
+ "@sanity/ui": "^0.37.9",
21
44
  "react-markdown": "^5.0.3",
22
45
  "react-mde": "^11.5.0",
23
46
  "remark-gfm": "^1.0.0"
24
47
  },
25
48
  "devDependencies": {
26
- "eslint": "^7.26.0",
49
+ "@commitlint/cli": "^16.1.0",
50
+ "@commitlint/config-conventional": "^15.0.0",
51
+ "@parcel/packager-ts": "^2.6.0",
52
+ "@parcel/transformer-typescript-types": "^2.6.0",
53
+ "@sanity/plugin-kit": "^0.0.1-studio-v3.4",
54
+ "@types/styled-components": "^5.1.25",
55
+ "@typescript-eslint/eslint-plugin": "^5.12.0",
56
+ "@typescript-eslint/parser": "^5.12.0",
57
+ "eslint": "^8.7.0",
27
58
  "eslint-config-prettier": "^8.3.0",
28
- "eslint-config-sanity": "5.1.0",
29
- "eslint-plugin-react": "^7.23.2",
30
- "prettier": "^2.3.0",
31
- "sanipack": "^2.0.1"
59
+ "eslint-config-sanity": "^5.1.0",
60
+ "eslint-plugin-prettier": "4.0.0",
61
+ "eslint-plugin-react": "^7.28.0",
62
+ "eslint-plugin-react-hooks": "^4.5.0",
63
+ "husky": "^7.0.0",
64
+ "lint-staged": "^12.3.3",
65
+ "parcel": "^2.6.0",
66
+ "prettier": "^2.5.1",
67
+ "react": "^17.0.0 || ^18.0.0",
68
+ "rimraf": "^3.0.2",
69
+ "sanity": "^3.0.0-dev-preview.7",
70
+ "styled-components": "^5.2.0",
71
+ "typescript": "^4.7.3"
32
72
  },
33
73
  "peerDependencies": {
34
- "@sanity/base": "^2.21.5",
35
- "react": "^17.0.0"
36
- },
37
- "prettier": {
38
- "semi": false,
39
- "printWidth": 100,
40
- "bracketSpacing": false,
41
- "singleQuote": true
42
- },
43
- "eslintConfig": {
44
- "parser": "sanipack/babel/eslint-parser",
45
- "extends": [
46
- "sanity",
47
- "sanity/react",
48
- "prettier",
49
- "prettier/react"
50
- ]
74
+ "react": "^17.0.0 || ^18.0.0",
75
+ "sanity": "dev-preview",
76
+ "styled-components": "^5.2.0"
51
77
  },
52
78
  "repository": {
53
79
  "type": "git",
@@ -56,5 +82,9 @@
56
82
  "bugs": {
57
83
  "url": "https://github.com/sanity-io/sanity-plugin-markdown/issues"
58
84
  },
59
- "homepage": "https://sanity.io"
85
+ "homepage": "https://sanity.io",
86
+ "sanityExchangeUrl": "https://www.sanity.io/plugins/sanity-plugin-markdown",
87
+ "engines": {
88
+ "node": ">=14.0.0"
89
+ }
60
90
  }
@@ -0,0 +1,164 @@
1
+ import ReactMde from 'react-mde'
2
+ import ReactMarkdown from 'react-markdown'
3
+ import gfm from 'remark-gfm'
4
+ import {useId} from '@reach/auto-id'
5
+
6
+ import useDebounce from '../hooks/useDebounce'
7
+ import 'react-mde/lib/styles/css/react-mde-all.css'
8
+ import {PatchEvent, set, unset} from 'sanity/form'
9
+ import {StringInputProps, useClient} from 'sanity'
10
+ import React, {
11
+ FC,
12
+ forwardRef,
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
+ `
73
+
74
+ export const MarkdownEditor = forwardRef(function MarkdownEditor(
75
+ props: StringInputProps,
76
+ ref: Ref<any>
77
+ ) {
78
+ const {schemaType: type, value = '', onBlur, onChange, onFocus, readOnly} = props
79
+ const options: {toolbar?: ToolbarCommands} | undefined = type.options as any
80
+ const [selectedTab, setSelectedTab] = useState<'write' | 'preview'>('write')
81
+ const [editedValue, setEditedValue] = useState(value)
82
+ const debouncedValue = useDebounce(editedValue, 100)
83
+ const textarea = useRef<HTMLTextAreaElement>(null)
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])
94
+
95
+ useEffect(() => {
96
+ setEditedValue(value)
97
+ }, [value])
98
+
99
+ useEffect(() => {
100
+ if (!debouncedValue && value) {
101
+ onChange(PatchEvent.from([unset()]))
102
+ } else if (debouncedValue !== value) {
103
+ onChange(PatchEvent.from([set(debouncedValue)]))
104
+ }
105
+ // eslint-disable-next-line react-hooks/exhaustive-deps
106
+ }, [debouncedValue, onChange])
107
+
108
+ const saveImage = async function* (data: any) {
109
+ const client = sanityClient.withConfig({apiVersion: '2021-03-25'})
110
+
111
+ let success = true
112
+ const result = await client.assets
113
+ .upload('image', data)
114
+ .then((doc) => `${doc.url}?w=450`)
115
+ .catch(() => {
116
+ success = false
117
+ return `Error: Could not upload file. Only images are supported.`
118
+ })
119
+
120
+ yield result
121
+ return success
122
+ }
123
+
124
+ const generatePreview = useCallback(
125
+ (markdown: string) => Promise.resolve(<Preview markdown={markdown} />),
126
+ []
127
+ )
128
+
129
+ const inputId = useId()
130
+ 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
+ return (
138
+ <div ref={ref}>
139
+ <MarkdownTheme studioTheme={studioTheme}>
140
+ <ReactMde
141
+ toolbarCommands={options?.toolbar || defaultToolbarCommands}
142
+ value={editedValue}
143
+ onChange={setEditedValue}
144
+ selectedTab={selectedTab}
145
+ onTabChange={setSelectedTab}
146
+ readOnly={readOnly}
147
+ generateMarkdownPreview={generatePreview}
148
+ childProps={{
149
+ textArea: {
150
+ id: inputId,
151
+ onBlur,
152
+ onFocus,
153
+ },
154
+ writeButton: {
155
+ tabIndex: -1,
156
+ },
157
+ }}
158
+ paste={{saveImage}}
159
+ refs={{textarea}}
160
+ />
161
+ </MarkdownTheme>
162
+ </div>
163
+ )
164
+ })
@@ -0,0 +1,14 @@
1
+ import {useState, useEffect} from 'react'
2
+
3
+ export default function useDebounce(value: unknown, delay: number) {
4
+ const [debouncedValue, setDebouncedValue] = useState(value)
5
+ useEffect(() => {
6
+ const handler = setTimeout(() => {
7
+ setDebouncedValue(value)
8
+ }, delay)
9
+
10
+ return () => clearTimeout(handler)
11
+ }, [value, delay])
12
+
13
+ return debouncedValue
14
+ }
package/src/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ import {MarkdownEditor} from './components/Editor'
2
+ import {createPlugin, defineType} from 'sanity'
3
+
4
+ export {MarkdownEditor}
5
+
6
+ export const markdownSchema = createPlugin({
7
+ name: 'markdown-editor',
8
+ schema: {
9
+ types: [
10
+ defineType({
11
+ type: 'string',
12
+ name: 'markdown',
13
+ title: 'Markdown',
14
+ components: {
15
+ input: MarkdownEditor,
16
+ },
17
+ }),
18
+ ],
19
+ },
20
+ })
@@ -1,22 +0,0 @@
1
- {
2
- "workbench.colorCustomizations": {
3
- "activityBar.activeBackground": "#ab307e",
4
- "activityBar.activeBorder": "#25320e",
5
- "activityBar.background": "#ab307e",
6
- "activityBar.foreground": "#e7e7e7",
7
- "activityBar.inactiveForeground": "#e7e7e799",
8
- "activityBarBadge.background": "#25320e",
9
- "activityBarBadge.foreground": "#e7e7e7",
10
- "sash.hoverBorder": "#ab307e",
11
- "statusBar.background": "#832561",
12
- "statusBar.foreground": "#e7e7e7",
13
- "statusBarItem.hoverBackground": "#ab307e",
14
- "statusBarItem.remoteBackground": "#832561",
15
- "statusBarItem.remoteForeground": "#e7e7e7",
16
- "titleBar.activeBackground": "#832561",
17
- "titleBar.activeForeground": "#e7e7e7",
18
- "titleBar.inactiveBackground": "#83256199",
19
- "titleBar.inactiveForeground": "#e7e7e799"
20
- },
21
- "peacock.color": "#832561"
22
- }
@@ -1,180 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var React = _interopRequireWildcard(require("react"));
9
-
10
- var _reactMde = _interopRequireDefault(require("react-mde"));
11
-
12
- var _reactMarkdown = _interopRequireDefault(require("react-markdown"));
13
-
14
- var _remarkGfm = _interopRequireDefault(require("remark-gfm"));
15
-
16
- var _autoId = require("@reach/auto-id");
17
-
18
- var _patchEvent = _interopRequireWildcard(require("part:@sanity/form-builder/patch-event"));
19
-
20
- var _client = _interopRequireDefault(require("part:@sanity/base/client"));
21
-
22
- var _components = require("@sanity/base/components");
23
-
24
- var _useDebounce = _interopRequireDefault(require("../hooks/useDebounce"));
25
-
26
- require("react-mde/lib/styles/css/react-mde-all.css?raw");
27
-
28
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
-
30
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
31
-
32
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
-
34
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
35
-
36
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
37
-
38
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
39
-
40
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
41
-
42
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
43
-
44
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
45
-
46
- function _awaitAsyncGenerator(value) { return new _AwaitValue(value); }
47
-
48
- function _wrapAsyncGenerator(fn) { return function () { return new _AsyncGenerator(fn.apply(this, arguments)); }; }
49
-
50
- function _AsyncGenerator(gen) { var front, back; function send(key, arg) { return new Promise(function (resolve, reject) { var request = { key: key, arg: arg, resolve: resolve, reject: reject, next: null }; if (back) { back = back.next = request; } else { front = back = request; resume(key, arg); } }); } function resume(key, arg) { try { var result = gen[key](arg); var value = result.value; var wrappedAwait = value instanceof _AwaitValue; Promise.resolve(wrappedAwait ? value.wrapped : value).then(function (arg) { if (wrappedAwait) { resume(key === "return" ? "return" : "next", arg); return; } settle(result.done ? "return" : "normal", arg); }, function (err) { resume("throw", err); }); } catch (err) { settle("throw", err); } } function settle(type, value) { switch (type) { case "return": front.resolve({ value: value, done: true }); break; case "throw": front.reject(value); break; default: front.resolve({ value: value, done: false }); break; } front = front.next; if (front) { resume(front.key, front.arg); } else { back = null; } } this._invoke = send; if (typeof gen.return !== "function") { this.return = undefined; } }
51
-
52
- _AsyncGenerator.prototype[typeof Symbol === "function" && Symbol.asyncIterator || "@@asyncIterator"] = function () { return this; };
53
-
54
- _AsyncGenerator.prototype.next = function (arg) { return this._invoke("next", arg); };
55
-
56
- _AsyncGenerator.prototype.throw = function (arg) { return this._invoke("throw", arg); };
57
-
58
- _AsyncGenerator.prototype.return = function (arg) { return this._invoke("return", arg); };
59
-
60
- function _AwaitValue(value) { this.wrapped = value; }
61
-
62
- var Preview = _ref2 => {
63
- var markdown = _ref2.markdown;
64
- return /*#__PURE__*/React.createElement(_reactMarkdown.default, {
65
- plugins: [_remarkGfm.default]
66
- }, markdown);
67
- };
68
-
69
- var defaultToolbarCommands = [['header', 'bold', 'italic', 'strikethrough'], ['link', 'quote', 'code'], ['unordered-list', 'ordered-list', 'checked-list']];
70
-
71
- var _default = /*#__PURE__*/React.forwardRef(function MarkdownEditor(props, ref) {
72
- var type = props.type,
73
- _props$value = props.value,
74
- value = _props$value === void 0 ? '' : _props$value,
75
- markers = props.markers,
76
- onBlur = props.onBlur,
77
- onChange = props.onChange,
78
- onFocus = props.onFocus,
79
- presence = props.presence,
80
- readOnly = props.readOnly;
81
- var _type$options = type.options,
82
- options = _type$options === void 0 ? {} : _type$options;
83
-
84
- var _React$useState = React.useState('write'),
85
- _React$useState2 = _slicedToArray(_React$useState, 2),
86
- selectedTab = _React$useState2[0],
87
- setSelectedTab = _React$useState2[1];
88
-
89
- var _React$useState3 = React.useState(value),
90
- _React$useState4 = _slicedToArray(_React$useState3, 2),
91
- editedValue = _React$useState4[0],
92
- setEditedValue = _React$useState4[1];
93
-
94
- var debouncedValue = (0, _useDebounce.default)(editedValue, 100);
95
- var textarea = React.useRef(); // Conditionally update textarea styles based on read only access.
96
- // It's also possible to define inline styles via `childProps.textArea.style` on `<ReactMde />`,
97
- // but this will override any dynamically created styles provided by the component itself.
98
-
99
- React.useEffect(() => {
100
- if (textarea.current) {
101
- textarea.current.style.backgroundColor = readOnly ? 'rgba(240,240,240)' : 'rgba(255,255,255)';
102
- }
103
- }, [textarea]);
104
- React.useEffect(() => {
105
- setEditedValue(value);
106
- }, [value]);
107
- React.useEffect(() => {
108
- if (!debouncedValue && value) {
109
- onChange(_patchEvent.default.from([(0, _patchEvent.unset)()]));
110
- } else if (debouncedValue !== value) {
111
- onChange(_patchEvent.default.from([(0, _patchEvent.set)(debouncedValue)]));
112
- }
113
- }, [debouncedValue]);
114
-
115
- var saveImage = /*#__PURE__*/function () {
116
- var _ref = _wrapAsyncGenerator(function* (data) {
117
- var client = _client.default.withConfig({
118
- apiVersion: '2021-03-25'
119
- });
120
-
121
- var success = true;
122
- var result = yield _awaitAsyncGenerator(client.assets.upload('image', data).then(doc => "".concat(doc.url, "?w=450")).catch(() => {
123
- success = false;
124
- return "Error: Could not upload file. Only images are supported.";
125
- }));
126
- yield result;
127
- return success;
128
- });
129
-
130
- return function saveImage(_x) {
131
- return _ref.apply(this, arguments);
132
- };
133
- }(); // Generate a random ID to link our FormField label and input component
134
-
135
-
136
- var inputId = (0, _autoId.useId)();
137
- return /*#__PURE__*/React.createElement(_components.FormField, {
138
- description: type.description // Creates description from schema
139
- ,
140
- inputId: inputId // A unique ID for this input
141
- ,
142
- title: type.title // Creates label from schema title
143
- ,
144
- __unstable_markers: markers // Handles all markers including validation
145
- ,
146
- __unstable_presence: presence // Handles presence avatars
147
-
148
- }, /*#__PURE__*/React.createElement("div", {
149
- ref: ref
150
- }, /*#__PURE__*/React.createElement(_reactMde.default, {
151
- toolbarCommands: options['toolbar'] || defaultToolbarCommands,
152
- value: editedValue,
153
- onChange: setEditedValue,
154
- selectedTab: selectedTab,
155
- onTabChange: setSelectedTab,
156
- readOnly: readOnly,
157
- generateMarkdownPreview: markdown => Promise.resolve( /*#__PURE__*/React.createElement(Preview, {
158
- markdown: markdown
159
- })),
160
- childProps: {
161
- textArea: {
162
- id: inputId,
163
- onBlur,
164
- onFocus
165
- },
166
- writeButton: {
167
- tabIndex: -1
168
- }
169
- },
170
- paste: {
171
- saveImage
172
- },
173
- refs: {
174
- textarea
175
- }
176
- })));
177
- });
178
-
179
- exports.default = _default;
180
- //# sourceMappingURL=Editor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/Editor.jsx"],"names":["Preview","markdown","gfm","defaultToolbarCommands","React","forwardRef","MarkdownEditor","props","ref","type","value","markers","onBlur","onChange","onFocus","presence","readOnly","options","useState","selectedTab","setSelectedTab","editedValue","setEditedValue","debouncedValue","textarea","useRef","useEffect","current","style","backgroundColor","PatchEvent","from","saveImage","data","client","sanityClient","withConfig","apiVersion","success","result","assets","upload","then","doc","url","catch","inputId","description","title","Promise","resolve","textArea","id","writeButton","tabIndex"],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport ReactMde from 'react-mde'\nimport ReactMarkdown from 'react-markdown'\nimport gfm from 'remark-gfm'\nimport {useId} from '@reach/auto-id'\n\nimport PatchEvent, {set, unset} from 'part:@sanity/form-builder/patch-event'\nimport sanityClient from 'part:@sanity/base/client'\nimport {FormField} from '@sanity/base/components'\n\nimport useDebounce from '../hooks/useDebounce'\n\nimport 'react-mde/lib/styles/css/react-mde-all.css?raw'\n\nconst Preview = ({markdown}) => {\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\nexport default React.forwardRef(function MarkdownEditor(props, ref) {\n const {type, value = '', markers, onBlur, onChange, onFocus, presence, readOnly} = props\n const {options = {}} = type\n const [selectedTab, setSelectedTab] = React.useState('write')\n const [editedValue, setEditedValue] = React.useState(value)\n const debouncedValue = useDebounce(editedValue, 100)\n const textarea = React.useRef()\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 React.useEffect(() => {\n if (textarea.current) {\n textarea.current.style.backgroundColor = readOnly ? 'rgba(240,240,240)' : 'rgba(255,255,255)'\n }\n }, [textarea])\n\n React.useEffect(() => {\n setEditedValue(value)\n }, [value])\n\n React.useEffect(() => {\n if (!debouncedValue && value) {\n onChange(PatchEvent.from([unset()]))\n } else if (debouncedValue !== value) {\n onChange(PatchEvent.from([set(debouncedValue)]))\n }\n }, [debouncedValue])\n\n const saveImage = async function* (data) {\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 // Generate a random ID to link our FormField label and input component\n const inputId = useId()\n\n return (\n <FormField\n description={type.description} // Creates description from schema\n inputId={inputId} // A unique ID for this input\n title={type.title} // Creates label from schema title\n __unstable_markers={markers} // Handles all markers including validation\n __unstable_presence={presence} // Handles presence avatars\n >\n {/*\n Assign our forwarded ref to a wrapper element.\n\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 <div ref={ref}>\n <ReactMde\n toolbarCommands={options['toolbar'] || defaultToolbarCommands}\n value={editedValue}\n onChange={setEditedValue}\n selectedTab={selectedTab}\n onTabChange={setSelectedTab}\n readOnly={readOnly}\n generateMarkdownPreview={(markdown) => Promise.resolve(<Preview markdown={markdown} />)}\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 </div>\n </FormField>\n )\n})\n"],"file":"Editor.js"}
@@ -1,40 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = useDebounce;
7
-
8
- var _react = _interopRequireWildcard(require("react"));
9
-
10
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
11
-
12
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
13
-
14
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
15
-
16
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
17
-
18
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
19
-
20
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
21
-
22
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
23
-
24
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
25
-
26
- function useDebounce(value, delay) {
27
- var _useState = (0, _react.useState)(value),
28
- _useState2 = _slicedToArray(_useState, 2),
29
- debouncedValue = _useState2[0],
30
- setDebouncedValue = _useState2[1];
31
-
32
- (0, _react.useEffect)(() => {
33
- var handler = setTimeout(() => {
34
- setDebouncedValue(value);
35
- }, delay);
36
- return () => clearTimeout(handler);
37
- }, [value]);
38
- return debouncedValue;
39
- }
40
- //# sourceMappingURL=useDebounce.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/hooks/useDebounce.js"],"names":["useDebounce","value","delay","debouncedValue","setDebouncedValue","handler","setTimeout","clearTimeout"],"mappings":";;;;;;;AAAA;;;;;;;;;;;;;;;;;;AACe,SAASA,WAAT,CAAqBC,KAArB,EAA4BC,KAA5B,EAAmC;AAChD,kBAA4C,qBAASD,KAAT,CAA5C;AAAA;AAAA,MAAOE,cAAP;AAAA,MAAuBC,iBAAvB;;AACA,wBAAU,MAAM;AACd,QAAMC,OAAO,GAAGC,UAAU,CAAC,MAAM;AAC/BF,MAAAA,iBAAiB,CAACH,KAAD,CAAjB;AACD,KAFyB,EAEvBC,KAFuB,CAA1B;AAIA,WAAO,MAAMK,YAAY,CAACF,OAAD,CAAzB;AACD,GAND,EAMG,CAACJ,KAAD,CANH;AAQA,SAAOE,cAAP;AACD","sourcesContent":["import React, {useState, useEffect} from 'react'\nexport default function useDebounce(value, delay) {\n const [debouncedValue, setDebouncedValue] = useState(value)\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value)\n }, delay)\n\n return () => clearTimeout(handler)\n }, [value])\n\n return debouncedValue\n}\n"],"file":"useDebounce.js"}
package/lib/schemaType.js DELETED
@@ -1,18 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _Editor = _interopRequireDefault(require("./components/Editor"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
-
12
- var _default = {
13
- type: 'string',
14
- name: 'markdown',
15
- inputComponent: _Editor.default
16
- };
17
- exports.default = _default;
18
- //# sourceMappingURL=schemaType.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schemaType.js"],"names":["type","name","inputComponent","Editor"],"mappings":";;;;;;;AAAA;;;;eAEe;AACbA,EAAAA,IAAI,EAAE,QADO;AAEbC,EAAAA,IAAI,EAAE,UAFO;AAGbC,EAAAA,cAAc,EAAEC;AAHH,C","sourcesContent":["import Editor from './components/Editor'\n\nexport default {\n type: 'string',\n name: 'markdown',\n inputComponent: Editor,\n}\n"],"file":"schemaType.js"}
package/sanity.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "paths": {
3
- "source": "./src",
4
- "compiled": "./lib"
5
- },
6
- "parts": [
7
- {
8
- "implements": "part:@sanity/base/schema-type",
9
- "path": "schemaType"
10
- }
11
- ]
12
- }