sanity-plugin-markdown 3.0.0-v3-studio.0 → 3.0.0-v3-studio.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Rune Botten
3
+ Copyright (c) 2022 Rune Botten
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -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. 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).
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
- ![Markdown input](assets/markdown-input.png)
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
- 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:
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
- ```bash
80
- npx yalc add sanity-plugin-markdown --link && yarn install
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
- 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.
83
+ ### Release new version
85
84
 
86
- ### About build & watch
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
- This plugin uses [@sanity/plugin-sdk](https://github.com/sanity-io/plugin-sdk)
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
- import { StringInputProps } from "sanity";
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
@@ -1 +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":"../"}
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',\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$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");
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 { 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");
41
+ const { value: value = "" , onBlur: onBlur , onChange: onChange , 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 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
- ]);
44
+ // const sanityClient = useClient()
125
45
  (0, $3KLdq$react.useEffect)(()=>{
126
46
  setEditedValue(value);
127
47
  }, [
@@ -139,63 +59,56 @@ const $067e75d167fd097d$export$18a9461578883ec4 = /*#__PURE__*/ (0, $3KLdq$react
139
59
  debouncedValue,
140
60
  onChange
141
61
  ]);
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", {
62
+ /* const saveImage = async function* (data: any) {
63
+ const client = sanityClient.withConfig({apiVersion: '2021-03-25'})
64
+
65
+ let success = true
66
+ const result = await client.assets
67
+ .upload('image', data)
68
+ .then((doc) => `${doc.url}?w=450`)
69
+ .catch(() => {
70
+ success = false
71
+ return `Error: Could not upload file. Only images are supported.`
72
+ })
73
+
74
+ yield result
75
+ return success
76
+ }*/ const { sanity: studioTheme } = (0, $3KLdq$sanityui.useTheme)();
77
+ return /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)("div", {
165
78
  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
- }
79
+ "data-color-mode": studioTheme.color.dark ? "dark" : "light",
80
+ children: readOnly ? /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, $3KLdq$sanityui.Card), {
81
+ border: true,
82
+ padding: 3,
83
+ children: /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, ($parcel$interopDefault($3KLdq$uiwreactmdeditor))).Markdown, {
84
+ source: value,
85
+ rehypePlugins: [
86
+ [
87
+ (0, ($parcel$interopDefault($3KLdq$rehypesanitize)))
88
+ ]
89
+ ]
192
90
  })
91
+ }) : /*#__PURE__*/ (0, $3KLdq$reactjsxruntime.jsx)((0, ($parcel$interopDefault($3KLdq$uiwreactmdeditor))), {
92
+ value: editedValue,
93
+ onChange: setEditedValue,
94
+ onBlur: onBlur,
95
+ onFocus: onFocus,
96
+ previewOptions: {
97
+ rehypePlugins: [
98
+ [
99
+ (0, ($parcel$interopDefault($3KLdq$rehypesanitize)))
100
+ ]
101
+ ]
102
+ },
103
+ preview: "edit"
193
104
  })
194
105
  });
195
106
  });
196
107
 
197
108
 
198
109
 
110
+ // re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:
111
+ const $244e63ca53592e4d$export$18a9461578883ec4 = (0, $067e75d167fd097d$export$18a9461578883ec4);
199
112
  const $244e63ca53592e4d$export$f225414958dd8925 = (0, $3KLdq$sanity.createPlugin)({
200
113
  name: "markdown-editor",
201
114
  schema: {
@@ -205,7 +118,7 @@ const $244e63ca53592e4d$export$f225414958dd8925 = (0, $3KLdq$sanity.createPlugin
205
118
  name: "markdown",
206
119
  title: "Markdown",
207
120
  components: {
208
- input: (0, $067e75d167fd097d$export$18a9461578883ec4)
121
+ input: $244e63ca53592e4d$export$18a9461578883ec4
209
122
  }
210
123
  }),
211
124
  ]
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',\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 {value = '', onBlur, onChange, onFocus, readOnly} = props\n const [editedValue, setEditedValue] = useState<string | undefined>(value)\n const debouncedValue = useDebounce(editedValue, 100)\n // const sanityClient = useClient()\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 {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":"../"}
@@ -1,17 +1,10 @@
1
- import {createPlugin as $jPEKE$createPlugin, defineType as $jPEKE$defineType, useClient as $jPEKE$useClient} from "sanity";
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$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";
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, 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
-
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 { 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");
32
+ const { value: value = "" , onBlur: onBlur , onChange: onChange , 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 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
- ]);
35
+ // const sanityClient = useClient()
116
36
  (0, $jPEKE$useEffect)(()=>{
117
37
  setEditedValue(value);
118
38
  }, [
@@ -130,63 +50,56 @@ const $483dd42bf797352b$export$18a9461578883ec4 = /*#__PURE__*/ (0, $jPEKE$forwa
130
50
  debouncedValue,
131
51
  onChange
132
52
  ]);
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", {
53
+ /* const saveImage = async function* (data: any) {
54
+ const client = sanityClient.withConfig({apiVersion: '2021-03-25'})
55
+
56
+ let success = true
57
+ const result = await client.assets
58
+ .upload('image', data)
59
+ .then((doc) => `${doc.url}?w=450`)
60
+ .catch(() => {
61
+ success = false
62
+ return `Error: Could not upload file. Only images are supported.`
63
+ })
64
+
65
+ yield result
66
+ return success
67
+ }*/ const { sanity: studioTheme } = (0, $jPEKE$useTheme)();
68
+ return /*#__PURE__*/ (0, $jPEKE$jsx)("div", {
156
69
  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
- }
70
+ "data-color-mode": studioTheme.color.dark ? "dark" : "light",
71
+ children: readOnly ? /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$Card), {
72
+ border: true,
73
+ padding: 3,
74
+ children: /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$uiwreactmdeditor).Markdown, {
75
+ source: value,
76
+ rehypePlugins: [
77
+ [
78
+ (0, $jPEKE$rehypesanitize)
79
+ ]
80
+ ]
183
81
  })
82
+ }) : /*#__PURE__*/ (0, $jPEKE$jsx)((0, $jPEKE$uiwreactmdeditor), {
83
+ value: editedValue,
84
+ onChange: setEditedValue,
85
+ onBlur: onBlur,
86
+ onFocus: onFocus,
87
+ previewOptions: {
88
+ rehypePlugins: [
89
+ [
90
+ (0, $jPEKE$rehypesanitize)
91
+ ]
92
+ ]
93
+ },
94
+ preview: "edit"
184
95
  })
185
96
  });
186
97
  });
187
98
 
188
99
 
189
100
 
101
+ // re-exporting MarkdownEditor directly explodes @parcel/transformer-typescript-types :shrug:
102
+ const $df9eabe9bda49ea8$export$18a9461578883ec4 = (0, $483dd42bf797352b$export$18a9461578883ec4);
190
103
  const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
191
104
  name: "markdown-editor",
192
105
  schema: {
@@ -196,7 +109,7 @@ const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
196
109
  name: "markdown",
197
110
  title: "Markdown",
198
111
  components: {
199
- input: (0, $483dd42bf797352b$export$18a9461578883ec4)
112
+ input: $df9eabe9bda49ea8$export$18a9461578883ec4
200
113
  }
201
114
  }),
202
115
  ]
@@ -204,5 +117,5 @@ const $df9eabe9bda49ea8$export$f225414958dd8925 = (0, $jPEKE$createPlugin)({
204
117
  });
205
118
 
206
119
 
207
- export {$df9eabe9bda49ea8$export$f225414958dd8925 as markdownSchema, $483dd42bf797352b$export$18a9461578883ec4 as MarkdownEditor};
120
+ export {$df9eabe9bda49ea8$export$18a9461578883ec4 as MarkdownEditor, $df9eabe9bda49ea8$export$f225414958dd8925 as markdownSchema};
208
121
  //# sourceMappingURL=index.modern.js.map
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;;;ACAA;;;;;ACAA;AAEe,kDAAqB,KAAc,EAAE,KAAa,EAAE;IACjE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,CAAC,KAAK,CAAC;IAC3D,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,MAAM,OAAO,GAAG,UAAU,CAAC,IAAM;YAC/B,iBAAiB,CAAC,KAAK,CAAC;SACzB,EAAE,KAAK,CAAC;QAET,OAAO,IAAM,YAAY,CAAC,OAAO,CAAC,CAAA;KACnC,EAAE;QAAC,KAAK;QAAE,KAAK;KAAC,CAAC;IAElB,OAAO,cAAc,CAAA;CACtB;;;;;;;;;ADUD,MAAM,6BAAO,GAAG,CAAC,YAAC,QAAQ,CAAA,EAAqB,GAAK;IAClD,qBAAO,gBAAC,CAAA,GAAA,oBAAa,CAAA;QAAC,OAAO,EAAE;YAAC,CAAA,GAAA,gBAAG,CAAA;SAAC;kBAAG,QAAQ;MAAiB,CAAA;CACjE;AAED,MAAM,4CAAsB,GAAG;IAC7B;QAAC,QAAQ;QAAE,MAAM;QAAE,QAAQ;QAAE,eAAe;KAAC;IAC7C;QAAC,MAAM;QAAE,OAAO;QAAE,MAAM;KAAC;IACzB;QAAC,gBAAgB;QAAE,cAAc;QAAE,cAAc;KAAC;CACnD;AAQD,+EAA+E;AAC/E,MAAM,mCAAa,GAAc,CAAA,GAAA,uBAAM,CAAA,CAAC,GAAG,CAAC;;kBAE1B,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;;;;gBAIpE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;WAC5E,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;;;;gBAIlE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;WACnE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;kBACvD,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;;;;aAIvE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;;;;oBAIvE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;;;;;gBAKtE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;WACnE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;iBACjE,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;kBACzD,EAAE,CAAC,eAAC,WAAW,CAAA,EAAQ,GAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;;AAEpF,CAAC;AAEM,MAAM,yCAAc,iBAAG,CAAA,GAAA,iBAAU,CAAA,CAAC,SAAS,cAAc,CAC9D,KAAuB,EACvB,GAAa,EACb;IACA,MAAM,EAAC,UAAU,EAAE,IAAI,CAAA,SAAE,KAAK,GAAG,EAAE,WAAE,MAAM,CAAA,YAAE,QAAQ,CAAA,WAAE,OAAO,CAAA,YAAE,QAAQ,CAAA,EAAC,GAAG,KAAK;IACjF,MAAM,OAAO,GAA4C,IAAI,CAAC,OAAO,AAAO;IAC5E,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,CAAsB,OAAO,CAAC;IAC5E,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,CAAC,KAAK,CAAC;IACrD,MAAM,cAAc,GAAG,CAAA,GAAA,wCAAW,CAAA,CAAC,WAAW,EAAE,GAAG,CAAC;IACpD,MAAM,QAAQ,GAAG,CAAA,GAAA,aAAM,CAAA,CAAsB,IAAI,CAAC;IAClD,MAAM,YAAY,GAAG,CAAA,GAAA,gBAAS,CAAA,EAAE;IAEhC,kEAAkE;IAClE,gGAAgG;IAChG,0FAA0F;IAC1F,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,IAAI,QAAQ,CAAC,OAAO,EAClB,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,QAAQ,GAAG,mBAAmB,GAAG,mBAAmB;KAEhG,EAAE;QAAC,QAAQ;QAAE,QAAQ;KAAC,CAAC;IAExB,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,cAAc,CAAC,KAAK,CAAC;KACtB,EAAE;QAAC,KAAK;KAAC,CAAC;IAEX,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,IAAI,CAAC,cAAc,IAAI,KAAK,EAC1B,QAAQ,CAAC,CAAA,GAAA,iBAAU,CAAA,CAAC,IAAI,CAAC;YAAC,CAAA,GAAA,YAAK,CAAA,EAAE;SAAC,CAAC,CAAC;aAC/B,IAAI,cAAc,KAAK,KAAK,EACjC,QAAQ,CAAC,CAAA,GAAA,iBAAU,CAAA,CAAC,IAAI,CAAC;YAAC,CAAA,GAAA,UAAG,CAAA,CAAC,cAAc,CAAC;SAAC,CAAC,CAAC;IAElD,uDAAuD;KACxD,EAAE;QAAC,cAAc;QAAE,QAAQ;KAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,gBAAiB,IAAS,EAAE;QAC5C,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC;YAAC,UAAU,EAAE,YAAY;SAAC,CAAC;QAElE,IAAI,OAAO,GAAG,IAAI;QAClB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAC/B,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CACrB,IAAI,CAAC,CAAC,GAAG,GAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CACjC,KAAK,CAAC,IAAM;YACX,OAAO,GAAG,KAAK;YACf,OAAO,CAAC,wDAAwD,CAAC,CAAA;SAClE,CAAC;QAEJ,MAAM,MAAM;QACZ,OAAO,OAAO,CAAA;KACf;IAED,MAAM,eAAe,GAAG,CAAA,GAAA,kBAAW,CAAA,CACjC,CAAC,QAAgB,GAAK,OAAO,CAAC,OAAO,eAAC,gBAAC,6BAAO;YAAC,QAAQ,EAAE,QAAQ;UAAI,CAAC,EACtE,EAAE,CACH;IAED,MAAM,OAAO,GAAG,CAAA,GAAA,YAAK,CAAA,EAAE;IACvB,MAAM,EAAC,MAAM,EAAE,WAAW,CAAA,EAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,EAAE;IACxC;;;;;IAKE,CACF,qBACE,gBAAC,KAAG;QAAC,GAAG,EAAE,GAAG;kBACX,cAAA,gBAAC,mCAAa;YAAC,WAAW,EAAE,WAAW;sBACrC,cAAA,gBAAC,CAAA,GAAA,eAAQ,CAAA;gBACP,eAAe,EAAE,OAAO,EAAE,OAAO,IAAI,4CAAsB;gBAC3D,KAAK,EAAE,WAAW;gBAClB,QAAQ,EAAE,cAAc;gBACxB,WAAW,EAAE,WAAW;gBACxB,WAAW,EAAE,cAAc;gBAC3B,QAAQ,EAAE,QAAQ;gBAClB,uBAAuB,EAAE,eAAe;gBACxC,UAAU,EAAE;oBACV,QAAQ,EAAE;wBACR,EAAE,EAAE,OAAO;gCACX,MAAM;iCACN,OAAO;qBACR;oBACD,WAAW,EAAE;wBACX,QAAQ,EAAE,EAAE;qBACb;iBACF;gBACD,KAAK,EAAE;+BAAC,SAAS;iBAAC;gBAClB,IAAI,EAAE;8BAAC,QAAQ;iBAAC;cAChB;UACY;MACZ,CACP;CACF,CAAC;;ADnKF;;AAKO,MAAM,yCAAc,GAAG,CAAA,GAAA,mBAAY,CAAA,CAAC;IACzC,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE;QACN,KAAK,EAAE;YACL,CAAA,GAAA,iBAAU,CAAA,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,UAAU;gBACjB,UAAU,EAAE;oBACV,KAAK,EAAE,CAAA,GAAA,yCAAc,CAAA;iBACtB;aACF,CAAC;SACH;KACF;CACF,CAAC","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":";;;;;;;;ACAA;;ACAA;AAEe,kDAAqB,KAAc,EAAE,KAAa,EAAE;IACjE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,CAAC,KAAK,CAAC;IAC3D,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,MAAM,OAAO,GAAG,UAAU,CAAC,IAAM;YAC/B,iBAAiB,CAAC,KAAK,CAAC;SACzB,EAAE,KAAK,CAAC;QAET,OAAO,IAAM,YAAY,CAAC,OAAO,CAAC,CAAA;KACnC,EAAE;QAAC,KAAK;QAAE,KAAK;KAAC,CAAC;IAElB,OAAO,cAAc,CAAA;CACtB;;;;;;;ADLM,MAAM,yCAAc,iBAAG,CAAA,GAAA,iBAAU,CAAA,CAAC,SAAS,cAAc,CAC9D,KAAuB,EACvB,GAAa,EACb;IACA,MAAM,SAAC,KAAK,GAAG,EAAE,WAAE,MAAM,CAAA,YAAE,QAAQ,CAAA,WAAE,OAAO,CAAA,YAAE,QAAQ,CAAA,EAAC,GAAG,KAAK;IAC/D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,CAAqB,KAAK,CAAC;IACzE,MAAM,cAAc,GAAG,CAAA,GAAA,wCAAW,CAAA,CAAC,WAAW,EAAE,GAAG,CAAC;IACpD,mCAAmC;IAEnC,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,cAAc,CAAC,KAAK,CAAC;KACtB,EAAE;QAAC,KAAK;KAAC,CAAC;IAEX,CAAA,GAAA,gBAAS,CAAA,CAAC,IAAM;QACd,IAAI,CAAC,cAAc,IAAI,KAAK,EAC1B,QAAQ,CAAC,CAAA,GAAA,iBAAU,CAAA,CAAC,IAAI,CAAC;YAAC,CAAA,GAAA,YAAK,CAAA,EAAE;SAAC,CAAC,CAAC;aAC/B,IAAI,cAAc,KAAK,KAAK,EACjC,QAAQ,CAAC,CAAA,GAAA,iBAAU,CAAA,CAAC,IAAI,CAAC;YAAC,CAAA,GAAA,UAAG,CAAA,CAAC,cAAc,CAAC;SAAC,CAAC,CAAC;IAElD,uDAAuD;KACxD,EAAE;QAAC,cAAc;QAAE,QAAQ;KAAC,CAAC;IAE9B;;;;;;;;;;;;;;KAcG,CAEH,MAAM,EAAC,MAAM,EAAE,WAAW,CAAA,EAAC,GAAG,CAAA,GAAA,eAAQ,CAAA,EAAE;IACxC,qBACE,gBAAC,KAAG;QAAC,GAAG,EAAE,GAAG;QAAE,iBAAe,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,OAAO;kBACtE,QAAQ,iBACP,gBAAC,CAAA,GAAA,WAAI,CAAA;YAAC,MAAM;YAAC,OAAO,EAAE,CAAC;sBACrB,cAAA,gBAAC,CAAA,GAAA,uBAAQ,CAAA,CAAC,QAAQ;gBAAC,MAAM,EAAE,KAAK;gBAAE,aAAa,EAAE;oBAAC;wBAAC,CAAA,GAAA,qBAAc,CAAA;qBAAC;iBAAC;cAAI;UAClE,iBAEP,gBAAC,CAAA,GAAA,uBAAQ,CAAA;YACP,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,cAAc;YACxB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,OAAO;YAChB,cAAc,EAAE;gBACd,aAAa,EAAE;oBAAC;wBAAC,CAAA,GAAA,qBAAc,CAAA;qBAAC;iBAAC;aAClC;YACD,OAAO,EAAC,MAAM;UACd,AACH;MACG,CACP;CACF,CAAC;;ADnEF;;AAGA,6FAA6F;AAC7F,MAAM,yCAAc,GAAG,CAAA,GAAA,yCAAM,CAAA;AAItB,MAAM,yCAAc,GAAG,CAAA,GAAA,mBAAY,CAAA,CAAC;IACzC,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE;QACN,KAAK,EAAE;YACL,CAAA,GAAA,iBAAU,CAAA,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,UAAU;gBACjB,UAAU,EAAE;oBACV,KAAK,EAAE,yCAAc;iBACtB;aACF,CAAC;SACH;KACF;CACF,CAAC","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',\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 {value = '', onBlur, onChange, onFocus, readOnly} = props\n const [editedValue, setEditedValue] = useState<string | undefined>(value)\n const debouncedValue = useDebounce(editedValue, 100)\n // const sanityClient = useClient()\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 {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.0",
3
+ "version": "3.0.0-v3-studio.1",
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": "^0.0.1-studio-v3.3",
42
+ "@sanity/incompatible-plugin": "^1.0.0",
43
43
  "@sanity/ui": "^0.37.9",
44
- "react-markdown": "^5.0.3",
45
- "react-mde": "^11.5.0",
46
- "remark-gfm": "^1.0.0"
44
+ "@uiw/react-md-editor": "^3.18.1",
45
+ "rehype-sanitize": "^5.0.1"
47
46
  },
48
47
  "devDependencies": {
49
48
  "@commitlint/cli": "^16.1.0",
50
49
  "@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",
50
+ "@parcel/packager-ts": "^2.7.0",
51
+ "@parcel/transformer-typescript-types": "^2.7.0",
52
+ "@sanity/plugin-kit": "^1.0.1",
53
+ "@sanity/semantic-release-preset": "^2.0.0",
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",
@@ -62,13 +62,13 @@
62
62
  "eslint-plugin-react-hooks": "^4.5.0",
63
63
  "husky": "^7.0.0",
64
64
  "lint-staged": "^12.3.3",
65
- "parcel": "^2.6.0",
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": "^3.0.0-dev-preview.7",
69
+ "sanity": "3.0.0-dev-preview.15",
70
70
  "styled-components": "^5.2.0",
71
- "typescript": "^4.7.3"
71
+ "typescript": "^4.8.2"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "react": "^17.0.0 || ^18.0.0",
@@ -1,96 +1,19 @@
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
-
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, 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
- `
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 {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)
13
+ const {value = '', onBlur, onChange, onFocus, readOnly} = props
14
+ const [editedValue, setEditedValue] = useState<string | undefined>(value)
82
15
  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])
16
+ // const sanityClient = useClient()
94
17
 
95
18
  useEffect(() => {
96
19
  setEditedValue(value)
@@ -105,7 +28,7 @@ export const MarkdownEditor = forwardRef(function MarkdownEditor(
105
28
  // eslint-disable-next-line react-hooks/exhaustive-deps
106
29
  }, [debouncedValue, onChange])
107
30
 
108
- const saveImage = async function* (data: any) {
31
+ /* const saveImage = async function* (data: any) {
109
32
  const client = sanityClient.withConfig({apiVersion: '2021-03-25'})
110
33
 
111
34
  let success = true
@@ -119,46 +42,27 @@ export const MarkdownEditor = forwardRef(function MarkdownEditor(
119
42
 
120
43
  yield result
121
44
  return success
122
- }
123
-
124
- const generatePreview = useCallback(
125
- (markdown: string) => Promise.resolve(<Preview markdown={markdown} />),
126
- []
127
- )
45
+ }*/
128
46
 
129
- const inputId = useId()
130
47
  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
48
  return (
138
- <div ref={ref}>
139
- <MarkdownTheme studioTheme={studioTheme}>
140
- <ReactMde
141
- toolbarCommands={options?.toolbar || defaultToolbarCommands}
49
+ <div ref={ref} data-color-mode={studioTheme.color.dark ? 'dark' : 'light'}>
50
+ {readOnly ? (
51
+ <Card border padding={3}>
52
+ <MDEditor.Markdown source={value} rehypePlugins={[[rehypeSanitize]]} />
53
+ </Card>
54
+ ) : (
55
+ <MDEditor
142
56
  value={editedValue}
143
57
  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
- },
58
+ onBlur={onBlur}
59
+ onFocus={onFocus}
60
+ previewOptions={{
61
+ rehypePlugins: [[rehypeSanitize]],
157
62
  }}
158
- paste={{saveImage}}
159
- refs={{textarea}}
63
+ preview="edit"
160
64
  />
161
- </MarkdownTheme>
65
+ )}
162
66
  </div>
163
67
  )
164
68
  })
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({