@sanity/code-input 2.29.5-get-started-template.13 → 2.29.5-purple-unicorn.779
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/CodeInput.js +7 -0
- package/deprecatedSchema.js +7 -0
- package/lib/CodeInput.cjs +39 -0
- package/lib/CodeInput.cjs.map +1 -0
- package/lib/CodeInput.js +33 -333
- package/lib/CodeInput.js.map +1 -0
- package/lib/_CodeInput-d6f5810b.js +846 -0
- package/lib/_CodeInput-d6f5810b.js.map +1 -0
- package/lib/_CodeInput-f70e9606.cjs +857 -0
- package/lib/_CodeInput-f70e9606.cjs.map +1 -0
- package/lib/_reExport.js +19 -0
- package/lib/deprecatedSchema.cjs +23 -0
- package/lib/deprecatedSchema.cjs.map +1 -0
- package/lib/deprecatedSchema.js +19 -24
- package/lib/deprecatedSchema.js.map +1 -0
- package/lib/dts/src/CodeInput.d.ts +17 -0
- package/lib/dts/src/CodeInput.d.ts.map +1 -0
- package/lib/dts/src/CodeInput.js +155 -0
- package/lib/dts/src/CodeInput.js.map +1 -0
- package/{dist/dts → lib/dts/src}/PreviewCode.d.ts +8 -8
- package/lib/dts/src/PreviewCode.d.ts.map +1 -0
- package/lib/dts/src/PreviewCode.js +50 -0
- package/lib/dts/src/PreviewCode.js.map +1 -0
- package/lib/dts/src/__workshop__/dev.d.ts +3 -0
- package/lib/dts/src/__workshop__/dev.d.ts.map +1 -0
- package/lib/dts/src/__workshop__/dev.js +18 -0
- package/lib/dts/src/__workshop__/dev.js.map +1 -0
- package/lib/dts/src/__workshop__/index.d.ts +3 -0
- package/lib/dts/src/__workshop__/index.d.ts.map +1 -0
- package/lib/dts/src/__workshop__/index.js +10 -0
- package/lib/dts/src/__workshop__/index.js.map +1 -0
- package/{dist/dts → lib/dts/src}/config.d.ts +15 -15
- package/lib/dts/src/config.d.ts.map +1 -0
- package/lib/dts/src/config.js +38 -0
- package/lib/dts/src/config.js.map +1 -0
- package/{dist/dts → lib/dts/src}/createHighlightMarkers.d.ts +3 -3
- package/lib/dts/src/createHighlightMarkers.d.ts.map +1 -0
- package/lib/dts/src/createHighlightMarkers.js +22 -0
- package/lib/dts/src/createHighlightMarkers.js.map +1 -0
- package/{dist/dts → lib/dts/src}/deprecatedSchema.d.ts +11 -11
- package/lib/dts/src/deprecatedSchema.d.ts.map +1 -0
- package/lib/dts/src/deprecatedSchema.js +19 -0
- package/lib/dts/src/deprecatedSchema.js.map +1 -0
- package/{dist/dts → lib/dts/src}/editorSupport.d.ts +27 -27
- package/lib/dts/src/editorSupport.d.ts.map +1 -0
- package/lib/dts/src/editorSupport.js +32 -0
- package/lib/dts/src/editorSupport.js.map +1 -0
- package/{dist/dts → lib/dts/src}/getMedia.d.ts +2 -2
- package/lib/dts/src/getMedia.d.ts.map +1 -0
- package/lib/dts/src/getMedia.js +35 -0
- package/lib/dts/src/getMedia.js.map +1 -0
- package/lib/dts/src/groq.d.ts +2 -0
- package/lib/dts/src/groq.d.ts.map +1 -0
- package/lib/dts/src/groq.js +612 -0
- package/lib/dts/src/groq.js.map +1 -0
- package/lib/dts/src/index.d.ts +4 -0
- package/lib/dts/src/index.d.ts.map +1 -0
- package/lib/dts/src/index.js +7 -0
- package/lib/dts/src/index.js.map +1 -0
- package/lib/dts/src/schema.d.ts +47 -0
- package/lib/dts/src/schema.d.ts.map +1 -0
- package/lib/dts/src/schema.js +59 -0
- package/lib/dts/src/schema.js.map +1 -0
- package/{dist/dts → lib/dts/src}/types.d.ts +28 -28
- package/lib/dts/src/types.d.ts.map +1 -0
- package/lib/dts/src/types.js +2 -0
- package/lib/dts/src/types.js.map +1 -0
- package/lib/dts/tsconfig.tsbuildinfo +1 -0
- package/lib/index.cjs +45 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.js +43 -0
- package/lib/index.js.map +1 -0
- package/lib/schema.cjs +174 -0
- package/lib/schema.cjs.map +1 -0
- package/lib/schema.js +159 -62
- package/lib/schema.js.map +1 -0
- package/package.json +63 -12
- package/schema.js +7 -0
- package/src/CodeInput.tsx +327 -0
- package/src/PreviewCode.tsx +89 -0
- package/src/__workshop__/dev.tsx +35 -0
- package/src/__workshop__/index.ts +10 -0
- package/src/config.ts +45 -0
- package/src/createHighlightMarkers.ts +24 -0
- package/src/deprecatedSchema.ts +19 -0
- package/src/editorSupport.ts +33 -0
- package/src/getMedia.tsx +95 -0
- package/src/groq.ts +630 -0
- package/src/index.ts +11 -0
- package/src/schema.tsx +69 -0
- package/src/types.ts +26 -0
- package/dist/dts/CodeInput.d.ts +0 -23
- package/dist/dts/CodeInput.d.ts.map +0 -1
- package/dist/dts/PreviewCode.d.ts.map +0 -1
- package/dist/dts/config.d.ts.map +0 -1
- package/dist/dts/createHighlightMarkers.d.ts.map +0 -1
- package/dist/dts/deprecatedSchema.d.ts.map +0 -1
- package/dist/dts/editorSupport.d.ts.map +0 -1
- package/dist/dts/getMedia.d.ts.map +0 -1
- package/dist/dts/groq.d.ts +0 -376
- package/dist/dts/groq.d.ts.map +0 -1
- package/dist/dts/schema.d.ts +0 -44
- package/dist/dts/schema.d.ts.map +0 -1
- package/dist/dts/types.d.ts.map +0 -1
- package/lib/@types/css.d.js +0 -1
- package/lib/PreviewCode.js +0 -79
- package/lib/config.js +0 -103
- package/lib/createHighlightMarkers.js +0 -31
- package/lib/editorSupport.js +0 -55
- package/lib/getMedia.js +0 -110
- package/lib/groq.js +0 -414
- package/lib/types.js +0 -5
- package/tsconfig.json +0 -26
package/package.json
CHANGED
|
@@ -1,13 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/code-input",
|
|
3
|
-
"version": "2.29.5-
|
|
3
|
+
"version": "2.29.5-purple-unicorn.779+195318940e",
|
|
4
4
|
"description": "Ace editor for editing code",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"source": "./src/index.ts",
|
|
6
|
+
"main": "./lib/index.cjs",
|
|
7
|
+
"module": "./lib/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"source": "./src/index.ts",
|
|
11
|
+
"require": "./lib/index.cjs",
|
|
12
|
+
"default": "./lib/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./CodeInput": {
|
|
15
|
+
"source": "./src/CodeInput.tsx",
|
|
16
|
+
"require": "./lib/CodeInput.cjs",
|
|
17
|
+
"default": "./lib/CodeInput.js"
|
|
18
|
+
},
|
|
19
|
+
"./schema": {
|
|
20
|
+
"source": "./src/schema.tsx",
|
|
21
|
+
"require": "./lib/schema.cjs",
|
|
22
|
+
"default": "./lib/schema.js"
|
|
23
|
+
},
|
|
24
|
+
"./deprecatedSchema": {
|
|
25
|
+
"source": "./src/deprecatedSchema.ts",
|
|
26
|
+
"require": "./lib/deprecatedSchema.cjs",
|
|
27
|
+
"default": "./lib/deprecatedSchema.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"types": "./lib/dts/src/index.d.ts",
|
|
31
|
+
"//": "the typesVersion config below is a workaround for TypeScript's lack of support for package exports",
|
|
32
|
+
"typesVersions": {
|
|
33
|
+
"*": {
|
|
34
|
+
"CodeInput": [
|
|
35
|
+
"./lib/dts/src/CodeInput.d.ts"
|
|
36
|
+
],
|
|
37
|
+
"schema": [
|
|
38
|
+
"./lib/dts/src/schema.d.ts"
|
|
39
|
+
],
|
|
40
|
+
"deprecatedSchema": [
|
|
41
|
+
"./lib/dts/src/deprecatedSchema.d.ts"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
7
45
|
"author": "Sanity.io <hello@sanity.io>",
|
|
8
46
|
"license": "MIT",
|
|
9
47
|
"scripts": {
|
|
10
|
-
"
|
|
48
|
+
"build": "../../../bin/pkg-utils bundle",
|
|
49
|
+
"clean": "rimraf lib",
|
|
50
|
+
"exports:check": "../../../bin/pkg-utils exports-check",
|
|
51
|
+
"exports:clean": "../../../bin/pkg-utils exports-clean",
|
|
52
|
+
"exports:generate": "../../../bin/pkg-utils exports-generate",
|
|
53
|
+
"postbuild": "run-s exports:generate",
|
|
54
|
+
"watch": "../../../bin/pkg-utils bundle --watch"
|
|
11
55
|
},
|
|
12
56
|
"keywords": [
|
|
13
57
|
"sanity",
|
|
@@ -20,19 +64,26 @@
|
|
|
20
64
|
"code-editor"
|
|
21
65
|
],
|
|
22
66
|
"dependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@sanity/
|
|
25
|
-
"@sanity/
|
|
26
|
-
"@sanity/types": "2.29.5-get-started-template.13+1f2e78fb8",
|
|
27
|
-
"@sanity/ui": "^0.37.6",
|
|
28
|
-
"@sanity/util": "2.29.5-get-started-template.13+1f2e78fb8",
|
|
67
|
+
"@sanity/icons": "^1.2.8",
|
|
68
|
+
"@sanity/ui": "^0.37.9",
|
|
69
|
+
"@sanity/util": "2.29.5-purple-unicorn.779+195318940e",
|
|
29
70
|
"ace-builds": "^1.4.13",
|
|
30
71
|
"react-ace": "^9.5.0"
|
|
31
72
|
},
|
|
32
73
|
"devDependencies": {
|
|
33
|
-
"
|
|
74
|
+
"@sanity/base": "2.29.5-purple-unicorn.779+195318940e",
|
|
75
|
+
"@sanity/form-builder": "2.30.0",
|
|
76
|
+
"@sanity/types": "2.29.5-purple-unicorn.779+195318940e",
|
|
77
|
+
"@sanity/ui-workshop": "^0.4.3",
|
|
78
|
+
"react": "17.0.2",
|
|
79
|
+
"rimraf": "^3.0.2",
|
|
80
|
+
"styled-components": "^5.2.0"
|
|
34
81
|
},
|
|
35
82
|
"peerDependencies": {
|
|
83
|
+
"@sanity/base": "^2.14",
|
|
84
|
+
"@sanity/form-builder": "^2.27",
|
|
85
|
+
"@sanity/types": "^2.14",
|
|
86
|
+
"@sanity/util": "2.27",
|
|
36
87
|
"prop-types": "^15.6 || ^16",
|
|
37
88
|
"react": "^16.9 || ^17",
|
|
38
89
|
"styled-components": "^5.2.0"
|
|
@@ -46,5 +97,5 @@
|
|
|
46
97
|
"url": "git+https://github.com/sanity-io/sanity.git",
|
|
47
98
|
"directory": "packages/@sanity/code-input"
|
|
48
99
|
},
|
|
49
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "195318940e367b7dc1cabb555faaa7998c489f81"
|
|
50
101
|
}
|
package/schema.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/* eslint-disable react/jsx-handler-names */
|
|
2
|
+
import React, {useCallback, useEffect, useImperativeHandle, useMemo, useRef} from 'react'
|
|
3
|
+
import {
|
|
4
|
+
FieldMember,
|
|
5
|
+
MemberField,
|
|
6
|
+
ObjectInputProps,
|
|
7
|
+
set,
|
|
8
|
+
setIfMissing,
|
|
9
|
+
unset,
|
|
10
|
+
} from '@sanity/base/form'
|
|
11
|
+
import {ObjectSchemaType} from '@sanity/types'
|
|
12
|
+
import {Card, Select, Stack} from '@sanity/ui'
|
|
13
|
+
import AceEditor from 'react-ace'
|
|
14
|
+
import styled from 'styled-components'
|
|
15
|
+
import createHighlightMarkers, {highlightMarkersCSS} from './createHighlightMarkers'
|
|
16
|
+
import {CodeInputLanguage, CodeInputValue} from './types'
|
|
17
|
+
/* eslint-disable-next-line import/no-unassigned-import */
|
|
18
|
+
import './editorSupport'
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
ACE_EDITOR_PROPS,
|
|
22
|
+
ACE_SET_OPTIONS,
|
|
23
|
+
DEFAULT_THEME,
|
|
24
|
+
LANGUAGE_ALIASES,
|
|
25
|
+
PATH_CODE,
|
|
26
|
+
SUPPORTED_LANGUAGES,
|
|
27
|
+
SUPPORTED_THEMES,
|
|
28
|
+
} from './config'
|
|
29
|
+
|
|
30
|
+
export type {CodeInputLanguage, CodeInputValue} from './types'
|
|
31
|
+
|
|
32
|
+
const EditorContainer = styled(Card)`
|
|
33
|
+
position: relative;
|
|
34
|
+
box-sizing: border-box;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
z-index: 0;
|
|
37
|
+
|
|
38
|
+
.ace_editor {
|
|
39
|
+
font-family: ${({theme}) => theme.sanity.fonts.code.family};
|
|
40
|
+
font-size: ${({theme}) => theme.sanity.fonts.code.sizes[1]};
|
|
41
|
+
line-height: inherit;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
${highlightMarkersCSS}
|
|
45
|
+
|
|
46
|
+
&:not([disabled]):not([readonly]) {
|
|
47
|
+
&:focus,
|
|
48
|
+
&:focus-within {
|
|
49
|
+
box-shadow: 0 0 0 2px ${({theme}) => theme.sanity.color.base.focusRing};
|
|
50
|
+
background-color: ${({theme}) => theme.sanity.color.base.bg};
|
|
51
|
+
border-color: ${({theme}) => theme.sanity.color.base.focusRing};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`
|
|
55
|
+
|
|
56
|
+
export type CodeSchemaType = Omit<ObjectSchemaType, 'options'> & {
|
|
57
|
+
options: {
|
|
58
|
+
theme?: string
|
|
59
|
+
languageAlternatives: CodeInputLanguage[]
|
|
60
|
+
language: string
|
|
61
|
+
withFilename?: boolean
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type CodeInputProps = ObjectInputProps<CodeInputValue, CodeSchemaType>
|
|
66
|
+
|
|
67
|
+
// Returns a string with the mode name if supported (because aliases), otherwise false
|
|
68
|
+
function isSupportedLanguage(mode: string) {
|
|
69
|
+
const alias = LANGUAGE_ALIASES[mode]
|
|
70
|
+
|
|
71
|
+
if (alias) {
|
|
72
|
+
return alias
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const isSupported = SUPPORTED_LANGUAGES.find((lang) => lang.value === mode)
|
|
76
|
+
if (isSupported) {
|
|
77
|
+
return mode
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function CodeInput(props: CodeInputProps) {
|
|
84
|
+
const {
|
|
85
|
+
focusRef,
|
|
86
|
+
members,
|
|
87
|
+
onBlur,
|
|
88
|
+
onChange,
|
|
89
|
+
onFocusPath,
|
|
90
|
+
readOnly,
|
|
91
|
+
renderField,
|
|
92
|
+
renderInput,
|
|
93
|
+
renderItem,
|
|
94
|
+
schemaType: type,
|
|
95
|
+
value,
|
|
96
|
+
} = props
|
|
97
|
+
|
|
98
|
+
const aceEditorRef = useRef<any>()
|
|
99
|
+
|
|
100
|
+
const fieldMembers = useMemo(
|
|
101
|
+
() => members.filter((member) => member.kind === 'field') as FieldMember[],
|
|
102
|
+
[members]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const languageFieldMember = fieldMembers.find((member) => member.name === 'language')
|
|
106
|
+
const filenameMember = fieldMembers.find((member) => member.name === 'filename')
|
|
107
|
+
const codeFieldMember = fieldMembers.find((member) => member.name === 'code')
|
|
108
|
+
|
|
109
|
+
useImperativeHandle(focusRef, () => ({
|
|
110
|
+
focus: () => {
|
|
111
|
+
aceEditorRef?.current?.editor?.focus()
|
|
112
|
+
},
|
|
113
|
+
}))
|
|
114
|
+
|
|
115
|
+
const handleCodeFocus = useCallback(() => {
|
|
116
|
+
onFocusPath(PATH_CODE)
|
|
117
|
+
}, [onFocusPath])
|
|
118
|
+
|
|
119
|
+
const getTheme = useCallback(() => {
|
|
120
|
+
const preferredTheme = type.options?.theme
|
|
121
|
+
return preferredTheme && SUPPORTED_THEMES.find((theme) => theme === preferredTheme)
|
|
122
|
+
? preferredTheme
|
|
123
|
+
: DEFAULT_THEME
|
|
124
|
+
}, [type])
|
|
125
|
+
|
|
126
|
+
const handleToggleSelectLine = useCallback(
|
|
127
|
+
(lineNumber: number) => {
|
|
128
|
+
const editorSession = aceEditorRef.current?.editor?.getSession()
|
|
129
|
+
const backgroundMarkers = editorSession?.getMarkers(true)
|
|
130
|
+
const currentHighlightedLines = Object.keys(backgroundMarkers)
|
|
131
|
+
.filter((key) => backgroundMarkers[key].type === 'screenLine')
|
|
132
|
+
.map((key) => backgroundMarkers[key].range.start.row)
|
|
133
|
+
const currentIndex = currentHighlightedLines.indexOf(lineNumber)
|
|
134
|
+
if (currentIndex > -1) {
|
|
135
|
+
// toggle remove
|
|
136
|
+
currentHighlightedLines.splice(currentIndex, 1)
|
|
137
|
+
} else {
|
|
138
|
+
// toggle add
|
|
139
|
+
currentHighlightedLines.push(lineNumber)
|
|
140
|
+
currentHighlightedLines.sort()
|
|
141
|
+
}
|
|
142
|
+
onChange(
|
|
143
|
+
set(
|
|
144
|
+
currentHighlightedLines.map(
|
|
145
|
+
(line) =>
|
|
146
|
+
// ace starts at line (row) 0, but we store it starting at line 1
|
|
147
|
+
line + 1
|
|
148
|
+
),
|
|
149
|
+
['highlightedLines']
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
},
|
|
153
|
+
[aceEditorRef, onChange]
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
const handleGutterMouseDown = useCallback(
|
|
157
|
+
(event: any) => {
|
|
158
|
+
const target = event.domEvent.target
|
|
159
|
+
if (target.classList.contains('ace_gutter-cell')) {
|
|
160
|
+
const row = event.getDocumentPosition().row
|
|
161
|
+
handleToggleSelectLine(row)
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
[handleToggleSelectLine]
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
const editor = aceEditorRef?.current?.editor
|
|
169
|
+
return () => {
|
|
170
|
+
editor?.session?.removeListener('guttermousedown', handleGutterMouseDown)
|
|
171
|
+
}
|
|
172
|
+
}, [aceEditorRef, handleGutterMouseDown])
|
|
173
|
+
|
|
174
|
+
const handleEditorLoad = useCallback(
|
|
175
|
+
(editor: any) => {
|
|
176
|
+
editor?.on('guttermousedown', handleGutterMouseDown)
|
|
177
|
+
},
|
|
178
|
+
[handleGutterMouseDown]
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
const getLanguageAlternatives = useCallback((): {
|
|
182
|
+
title: string
|
|
183
|
+
value: string
|
|
184
|
+
mode?: string
|
|
185
|
+
}[] => {
|
|
186
|
+
const languageAlternatives = type.options?.languageAlternatives
|
|
187
|
+
if (!languageAlternatives) {
|
|
188
|
+
return SUPPORTED_LANGUAGES
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!Array.isArray(languageAlternatives)) {
|
|
192
|
+
throw new Error(
|
|
193
|
+
`'options.languageAlternatives' should be an array, got ${typeof languageAlternatives}`
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return languageAlternatives.reduce((acc: CodeInputLanguage[], {title, value: val, mode}) => {
|
|
198
|
+
const alias = LANGUAGE_ALIASES[val]
|
|
199
|
+
if (alias) {
|
|
200
|
+
// eslint-disable-next-line no-console
|
|
201
|
+
console.warn(
|
|
202
|
+
`'options.languageAlternatives' lists a language with value "%s", which is an alias of "%s" - please replace the value to read "%s"`,
|
|
203
|
+
val,
|
|
204
|
+
alias,
|
|
205
|
+
alias
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return acc.concat({title, value: alias, mode: mode})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!mode && !SUPPORTED_LANGUAGES.find((lang) => lang.value === val)) {
|
|
212
|
+
// eslint-disable-next-line no-console
|
|
213
|
+
console.warn(
|
|
214
|
+
`'options.languageAlternatives' lists a language which is not supported: "%s", syntax highlighting will be disabled.`,
|
|
215
|
+
val
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return acc.concat({title, value: val, mode})
|
|
220
|
+
}, [])
|
|
221
|
+
}, [type])
|
|
222
|
+
|
|
223
|
+
const handleCodeChange = useCallback(
|
|
224
|
+
(code: string) => {
|
|
225
|
+
const path = PATH_CODE
|
|
226
|
+
const fixedLanguage = type.options?.language
|
|
227
|
+
|
|
228
|
+
onChange([
|
|
229
|
+
setIfMissing({_type: type.name, language: fixedLanguage}),
|
|
230
|
+
code ? set(code, path) : unset(path),
|
|
231
|
+
])
|
|
232
|
+
},
|
|
233
|
+
[onChange, type]
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
const languages = getLanguageAlternatives().slice()
|
|
237
|
+
|
|
238
|
+
const fixedLanguage = type.options?.language
|
|
239
|
+
|
|
240
|
+
const language = value?.language || fixedLanguage
|
|
241
|
+
|
|
242
|
+
// the language config from the schema
|
|
243
|
+
const configured = languages.find((entry) => entry.value === language)
|
|
244
|
+
|
|
245
|
+
// is the language officially supported (e.g. we import the mode by default)
|
|
246
|
+
const supported = language && isSupportedLanguage(language)
|
|
247
|
+
|
|
248
|
+
const mode = configured?.mode || (supported ? language : 'text')
|
|
249
|
+
|
|
250
|
+
const renderLanguageInput = useCallback(
|
|
251
|
+
(inputProps) => {
|
|
252
|
+
return (
|
|
253
|
+
<Select {...inputProps}>
|
|
254
|
+
{languages.map((lang: {title: string; value: string}) => (
|
|
255
|
+
<option key={lang.value} value={lang.value}>
|
|
256
|
+
{lang.title}
|
|
257
|
+
</option>
|
|
258
|
+
))}
|
|
259
|
+
</Select>
|
|
260
|
+
)
|
|
261
|
+
},
|
|
262
|
+
[languages]
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
const renderCodeInput = useCallback(
|
|
266
|
+
(inputProps) => {
|
|
267
|
+
return (
|
|
268
|
+
<EditorContainer radius={1} shadow={1} readOnly={readOnly}>
|
|
269
|
+
<AceEditor
|
|
270
|
+
ref={aceEditorRef}
|
|
271
|
+
mode={mode}
|
|
272
|
+
theme={getTheme()}
|
|
273
|
+
width="100%"
|
|
274
|
+
onChange={handleCodeChange}
|
|
275
|
+
name={inputProps.id}
|
|
276
|
+
value={inputProps.value}
|
|
277
|
+
markers={
|
|
278
|
+
value && value.highlightedLines
|
|
279
|
+
? createHighlightMarkers(value.highlightedLines)
|
|
280
|
+
: undefined
|
|
281
|
+
}
|
|
282
|
+
onLoad={handleEditorLoad}
|
|
283
|
+
readOnly={readOnly}
|
|
284
|
+
tabSize={2}
|
|
285
|
+
wrapEnabled
|
|
286
|
+
setOptions={ACE_SET_OPTIONS}
|
|
287
|
+
editorProps={ACE_EDITOR_PROPS}
|
|
288
|
+
onFocus={handleCodeFocus}
|
|
289
|
+
onBlur={onBlur}
|
|
290
|
+
/>
|
|
291
|
+
</EditorContainer>
|
|
292
|
+
)
|
|
293
|
+
},
|
|
294
|
+
[getTheme, handleCodeChange, handleCodeFocus, handleEditorLoad, mode, onBlur, readOnly, value]
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<Stack space={4}>
|
|
299
|
+
{languageFieldMember && (
|
|
300
|
+
<MemberField
|
|
301
|
+
member={languageFieldMember}
|
|
302
|
+
renderItem={renderItem}
|
|
303
|
+
renderField={renderField}
|
|
304
|
+
renderInput={renderLanguageInput}
|
|
305
|
+
/>
|
|
306
|
+
)}
|
|
307
|
+
|
|
308
|
+
{type.options?.withFilename && filenameMember && (
|
|
309
|
+
<MemberField
|
|
310
|
+
member={filenameMember}
|
|
311
|
+
renderItem={renderItem}
|
|
312
|
+
renderField={renderField}
|
|
313
|
+
renderInput={renderInput}
|
|
314
|
+
/>
|
|
315
|
+
)}
|
|
316
|
+
|
|
317
|
+
{codeFieldMember && (
|
|
318
|
+
<MemberField
|
|
319
|
+
member={codeFieldMember}
|
|
320
|
+
renderInput={renderCodeInput}
|
|
321
|
+
renderItem={renderItem}
|
|
322
|
+
renderField={renderField}
|
|
323
|
+
/>
|
|
324
|
+
)}
|
|
325
|
+
</Stack>
|
|
326
|
+
)
|
|
327
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, {useCallback, useEffect, useRef} from 'react'
|
|
2
|
+
import AceEditor from 'react-ace'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import {Box} from '@sanity/ui'
|
|
5
|
+
import {ACE_EDITOR_PROPS, ACE_SET_OPTIONS} from './config'
|
|
6
|
+
import createHighlightMarkers from './createHighlightMarkers'
|
|
7
|
+
import {CodeInputType, CodeInputValue} from './types'
|
|
8
|
+
/* eslint-disable-next-line import/no-unassigned-import */
|
|
9
|
+
import './editorSupport'
|
|
10
|
+
|
|
11
|
+
const PreviewContainer = styled(Box)`
|
|
12
|
+
position: relative;
|
|
13
|
+
`
|
|
14
|
+
|
|
15
|
+
const PreviewInner = styled(Box)`
|
|
16
|
+
background-color: #272822;
|
|
17
|
+
|
|
18
|
+
.ace_editor {
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
cursor: default;
|
|
21
|
+
pointer-events: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ace_content {
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
export interface PreviewCodeProps {
|
|
31
|
+
type?: CodeInputType
|
|
32
|
+
value?: CodeInputValue
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default function PreviewCode(props: PreviewCodeProps) {
|
|
36
|
+
const aceEditorRef = useRef<any>()
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!aceEditorRef?.current) return
|
|
40
|
+
|
|
41
|
+
const editor = aceEditorRef.current?.editor
|
|
42
|
+
|
|
43
|
+
if (editor) {
|
|
44
|
+
// Avoid cursor and focus tracking by Ace
|
|
45
|
+
editor.renderer.$cursorLayer.element.style.opacity = 0
|
|
46
|
+
editor.textInput.getElement().disabled = true
|
|
47
|
+
}
|
|
48
|
+
}, [])
|
|
49
|
+
|
|
50
|
+
const handleEditorChange = useCallback(() => {
|
|
51
|
+
// do nothing when the editor changes
|
|
52
|
+
}, [])
|
|
53
|
+
|
|
54
|
+
const {value, type} = props
|
|
55
|
+
const fixedLanguage = type?.options?.language
|
|
56
|
+
|
|
57
|
+
const mode = value?.language || fixedLanguage || 'text'
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<PreviewContainer>
|
|
61
|
+
<PreviewInner padding={4}>
|
|
62
|
+
<AceEditor
|
|
63
|
+
ref={aceEditorRef}
|
|
64
|
+
focus={false}
|
|
65
|
+
mode={mode}
|
|
66
|
+
theme="monokai"
|
|
67
|
+
width="100%"
|
|
68
|
+
onChange={handleEditorChange}
|
|
69
|
+
maxLines={200}
|
|
70
|
+
readOnly
|
|
71
|
+
wrapEnabled
|
|
72
|
+
showPrintMargin={false}
|
|
73
|
+
highlightActiveLine={false}
|
|
74
|
+
cursorStart={-1}
|
|
75
|
+
value={(value && value.code) || ''}
|
|
76
|
+
markers={
|
|
77
|
+
value && value.highlightedLines
|
|
78
|
+
? createHighlightMarkers(value.highlightedLines)
|
|
79
|
+
: undefined
|
|
80
|
+
}
|
|
81
|
+
tabSize={2}
|
|
82
|
+
showGutter={false}
|
|
83
|
+
setOptions={ACE_SET_OPTIONS}
|
|
84
|
+
editorProps={ACE_EDITOR_PROPS}
|
|
85
|
+
/>
|
|
86
|
+
</PreviewInner>
|
|
87
|
+
</PreviewContainer>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {createSchema} from '@sanity/base/_unstable'
|
|
2
|
+
import {ValidationMarker, Path} from '@sanity/types'
|
|
3
|
+
import {Box} from '@sanity/ui'
|
|
4
|
+
import {useAction} from '@sanity/ui-workshop'
|
|
5
|
+
import React, {useState} from 'react'
|
|
6
|
+
import {CodeInput, CodeSchemaType} from '../CodeInput'
|
|
7
|
+
import typeDef from '../schema'
|
|
8
|
+
|
|
9
|
+
const schema = createSchema({name: 'dev', types: [typeDef]})
|
|
10
|
+
const schemaType = schema.get('code') as CodeSchemaType
|
|
11
|
+
|
|
12
|
+
export default function DevStory() {
|
|
13
|
+
const [focusPath] = useState<Path>([])
|
|
14
|
+
const [validation] = useState<ValidationMarker[]>([])
|
|
15
|
+
const onBlur = useAction('onBlur')
|
|
16
|
+
const onChange = useAction('onChange')
|
|
17
|
+
const onFocus = useAction('onFocus')
|
|
18
|
+
const [presence] = useState<any[]>([])
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Box padding={4}>
|
|
22
|
+
<>TODO</>
|
|
23
|
+
{/* <CodeInput
|
|
24
|
+
focusPath={focusPath}
|
|
25
|
+
level={0}
|
|
26
|
+
validation={validation}
|
|
27
|
+
onBlur={onBlur}
|
|
28
|
+
onChange={onChange}
|
|
29
|
+
onFocus={onFocus}
|
|
30
|
+
presence={presence}
|
|
31
|
+
schemaType={schemaType}
|
|
32
|
+
/> */}
|
|
33
|
+
</Box>
|
|
34
|
+
)
|
|
35
|
+
}
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {CodeInputLanguage} from './types'
|
|
2
|
+
|
|
3
|
+
// NOTE: MAKE SURE THESE ALIGN WITH IMPORTS IN ./editorSupport
|
|
4
|
+
export const SUPPORTED_LANGUAGES: CodeInputLanguage[] = [
|
|
5
|
+
{title: 'Batch file', value: 'batchfile'},
|
|
6
|
+
{title: 'C#', value: 'csharp'},
|
|
7
|
+
{title: 'CSS', value: 'css'},
|
|
8
|
+
{title: 'Go', value: 'golang'},
|
|
9
|
+
{title: 'GROQ', value: 'groq'},
|
|
10
|
+
{title: 'HTML', value: 'html'},
|
|
11
|
+
{title: 'Java', value: 'java'},
|
|
12
|
+
{title: 'JavaScript', value: 'javascript'},
|
|
13
|
+
{title: 'JSON', value: 'json'},
|
|
14
|
+
{title: 'JSX', value: 'jsx'},
|
|
15
|
+
{title: 'Markdown', value: 'markdown'},
|
|
16
|
+
{title: 'MySQL', value: 'mysql'},
|
|
17
|
+
{title: 'PHP', value: 'php'},
|
|
18
|
+
{title: 'Plain text', value: 'text'},
|
|
19
|
+
{title: 'Python', value: 'python'},
|
|
20
|
+
{title: 'Ruby', value: 'ruby'},
|
|
21
|
+
{title: 'SASS', value: 'sass'},
|
|
22
|
+
{title: 'SCSS', value: 'scss'},
|
|
23
|
+
{title: 'sh', value: 'sh'},
|
|
24
|
+
{title: 'TSX', value: 'tsx'},
|
|
25
|
+
{title: 'TypeScript', value: 'typescript'},
|
|
26
|
+
{title: 'XML', value: 'xml'},
|
|
27
|
+
{title: 'YAML', value: 'yaml'},
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
export const LANGUAGE_ALIASES: Record<string, string | undefined> = {js: 'javascript'}
|
|
31
|
+
|
|
32
|
+
export const SUPPORTED_THEMES = ['github', 'monokai', 'terminal', 'tomorrow']
|
|
33
|
+
|
|
34
|
+
export const DEFAULT_THEME = 'tomorrow'
|
|
35
|
+
|
|
36
|
+
export const ACE_SET_OPTIONS = {
|
|
37
|
+
useSoftTabs: true,
|
|
38
|
+
navigateWithinSoftTabs: true /* note only supported by ace v1.2.7 or higher */,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const ACE_EDITOR_PROPS = {$blockScrolling: true}
|
|
42
|
+
|
|
43
|
+
export const PATH_LANGUAGE = ['language']
|
|
44
|
+
export const PATH_CODE = ['code']
|
|
45
|
+
export const PATH_FILENAME = ['filename']
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {IMarker} from 'react-ace'
|
|
2
|
+
import {css} from 'styled-components'
|
|
3
|
+
|
|
4
|
+
export const highlightMarkersCSS = css`
|
|
5
|
+
.ace_editor_markers_highlight {
|
|
6
|
+
position: absolute;
|
|
7
|
+
background-color: ${({theme}) => theme.sanity.color.solid.primary.enabled.bg};
|
|
8
|
+
opacity: 0.2;
|
|
9
|
+
width: 100% !important;
|
|
10
|
+
border-radius: 0 !important;
|
|
11
|
+
}
|
|
12
|
+
`
|
|
13
|
+
|
|
14
|
+
export default function createHighlightMarkers(rows: number[]): IMarker[] {
|
|
15
|
+
return rows.map((row) => ({
|
|
16
|
+
startRow: Number(row) - 1,
|
|
17
|
+
startCol: 0,
|
|
18
|
+
endRow: Number(row) - 1,
|
|
19
|
+
endCol: +Infinity,
|
|
20
|
+
className: 'ace_editor_markers_highlight',
|
|
21
|
+
type: 'screenLine',
|
|
22
|
+
inFront: true,
|
|
23
|
+
}))
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default (() => {
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
console.warn('@sanity/code-input has been upgraded to automatically register its schema type.')
|
|
4
|
+
console.warn('Please remove the explicit import of `part:@sanity/base/schema-type`')
|
|
5
|
+
/* eslint-enable no-console */
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
name: 'oldDeprecatedCodeTypeWhichYouShouldRemove',
|
|
9
|
+
type: 'object',
|
|
10
|
+
title: 'Deprecated code type',
|
|
11
|
+
fields: [
|
|
12
|
+
{
|
|
13
|
+
title: 'Code',
|
|
14
|
+
name: 'code',
|
|
15
|
+
type: 'text',
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
}
|
|
19
|
+
})()
|