@sanity/code-input 2.30.2-shopify.2 → 3.0.0-studio-v3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +65 -9
  2. package/lib/cjs/index.js +1351 -0
  3. package/lib/cjs/index.js.map +1 -0
  4. package/lib/esm/index.js +1343 -0
  5. package/lib/esm/index.js.map +1 -0
  6. package/lib/types/index.d.ts +48 -0
  7. package/lib/types/index.d.ts.map +1 -0
  8. package/package.json +61 -18
  9. package/sanity.json +2 -22
  10. package/src/CodeInput.tsx +336 -0
  11. package/src/PreviewCode.tsx +88 -0
  12. package/src/config.ts +46 -0
  13. package/src/createHighlightMarkers.ts +24 -0
  14. package/src/editorSupport.ts +31 -0
  15. package/src/getMedia.tsx +95 -0
  16. package/src/groq.ts +630 -0
  17. package/src/index.ts +12 -0
  18. package/src/schema.tsx +69 -0
  19. package/src/types.ts +26 -0
  20. package/v2-incompatible.js +11 -0
  21. package/dist/dts/CodeInput.d.ts +0 -22
  22. package/dist/dts/CodeInput.d.ts.map +0 -1
  23. package/dist/dts/PreviewCode.d.ts +0 -9
  24. package/dist/dts/PreviewCode.d.ts.map +0 -1
  25. package/dist/dts/config.d.ts +0 -16
  26. package/dist/dts/config.d.ts.map +0 -1
  27. package/dist/dts/createHighlightMarkers.d.ts +0 -4
  28. package/dist/dts/createHighlightMarkers.d.ts.map +0 -1
  29. package/dist/dts/deprecatedSchema.d.ts +0 -12
  30. package/dist/dts/deprecatedSchema.d.ts.map +0 -1
  31. package/dist/dts/editorSupport.d.ts +0 -28
  32. package/dist/dts/editorSupport.d.ts.map +0 -1
  33. package/dist/dts/getMedia.d.ts +0 -3
  34. package/dist/dts/getMedia.d.ts.map +0 -1
  35. package/dist/dts/groq.d.ts +0 -376
  36. package/dist/dts/groq.d.ts.map +0 -1
  37. package/dist/dts/schema.d.ts +0 -44
  38. package/dist/dts/schema.d.ts.map +0 -1
  39. package/dist/dts/types.d.ts +0 -29
  40. package/dist/dts/types.d.ts.map +0 -1
  41. package/lib/@types/css.d.js +0 -1
  42. package/lib/CodeInput.js +0 -325
  43. package/lib/PreviewCode.js +0 -79
  44. package/lib/config.js +0 -103
  45. package/lib/createHighlightMarkers.js +0 -31
  46. package/lib/deprecatedSchema.js +0 -26
  47. package/lib/editorSupport.js +0 -55
  48. package/lib/getMedia.js +0 -110
  49. package/lib/groq.js +0 -414
  50. package/lib/schema.js +0 -69
  51. package/lib/types.js +0 -5
  52. package/tsconfig.json +0 -26
@@ -0,0 +1,336 @@
1
+ /* eslint-disable react/jsx-handler-names */
2
+ import React, {useCallback, useEffect, useImperativeHandle, useMemo, useRef} from 'react'
3
+ import {FieldMember, MemberField, ObjectInputProps, set, setIfMissing, unset} from 'sanity/form'
4
+ import {ObjectSchemaType} from 'sanity'
5
+ import {Card, Select, Stack} from '@sanity/ui'
6
+ import AceEditor from 'react-ace'
7
+ import styled from 'styled-components'
8
+ import createHighlightMarkers, {highlightMarkersCSS} from './createHighlightMarkers'
9
+ import {CodeInputLanguage, CodeInputValue} from './types'
10
+ import './editorSupport'
11
+
12
+ import {
13
+ ACE_EDITOR_PROPS,
14
+ ACE_SET_OPTIONS,
15
+ DEFAULT_DARK_THEME,
16
+ DEFAULT_THEME,
17
+ LANGUAGE_ALIASES,
18
+ PATH_CODE,
19
+ SUPPORTED_LANGUAGES,
20
+ SUPPORTED_THEMES,
21
+ } from './config'
22
+ import {useColorScheme, InputProps, StringInputProps} from 'sanity'
23
+
24
+ export type {CodeInputLanguage, CodeInputValue} from './types'
25
+
26
+ const EditorContainer = styled(Card)`
27
+ position: relative;
28
+ box-sizing: border-box;
29
+ overflow: hidden;
30
+ z-index: 0;
31
+
32
+ .ace_editor {
33
+ font-family: ${({theme}) => theme.sanity.fonts.code.family};
34
+ font-size: ${({theme}) => theme.sanity.fonts.code.sizes[1]};
35
+ line-height: inherit;
36
+ }
37
+
38
+ ${highlightMarkersCSS}
39
+
40
+ &:not([disabled]):not([readonly]) {
41
+ &:focus,
42
+ &:focus-within {
43
+ box-shadow: 0 0 0 2px ${({theme}) => theme.sanity.color.base.focusRing};
44
+ background-color: ${({theme}) => theme.sanity.color.base.bg};
45
+ border-color: ${({theme}) => theme.sanity.color.base.focusRing};
46
+ }
47
+ }
48
+ `
49
+
50
+ export type CodeSchemaType = Omit<ObjectSchemaType, 'options'> & {
51
+ options: {
52
+ theme?: string
53
+ darkTheme?: string
54
+ languageAlternatives: CodeInputLanguage[]
55
+ language: string
56
+ withFilename?: boolean
57
+ }
58
+ }
59
+
60
+ export type CodeInputProps = ObjectInputProps<CodeInputValue, CodeSchemaType>
61
+
62
+ // Returns a string with the mode name if supported (because aliases), otherwise false
63
+ function isSupportedLanguage(mode: string) {
64
+ const alias = LANGUAGE_ALIASES[mode]
65
+
66
+ if (alias) {
67
+ return alias
68
+ }
69
+
70
+ const isSupported = SUPPORTED_LANGUAGES.find((lang) => lang.value === mode)
71
+ if (isSupported) {
72
+ return mode
73
+ }
74
+
75
+ return false
76
+ }
77
+
78
+ export function CodeInput(props: CodeInputProps) {
79
+ const {
80
+ focusRef,
81
+ members,
82
+ onBlur,
83
+ onChange,
84
+ onFocusPath,
85
+ readOnly,
86
+ renderField,
87
+ renderInput,
88
+ renderItem,
89
+ renderPreview,
90
+ schemaType: type,
91
+ value,
92
+ } = props
93
+
94
+ const aceEditorRef = useRef<any>()
95
+
96
+ const fieldMembers = useMemo(
97
+ () => members.filter((member) => member.kind === 'field') as FieldMember[],
98
+ [members]
99
+ )
100
+
101
+ const languageFieldMember = fieldMembers.find((member) => member.name === 'language')
102
+ const filenameMember = fieldMembers.find((member) => member.name === 'filename')
103
+ const codeFieldMember = fieldMembers.find((member) => member.name === 'code')
104
+
105
+ useImperativeHandle(focusRef, () => ({
106
+ focus: () => {
107
+ aceEditorRef?.current?.editor?.focus()
108
+ },
109
+ }))
110
+
111
+ const handleCodeFocus = useCallback(() => {
112
+ onFocusPath(PATH_CODE)
113
+ }, [onFocusPath])
114
+
115
+ const {scheme} = useColorScheme()
116
+
117
+ const theme = useMemo(() => {
118
+ const isLight = scheme === 'light'
119
+ const preferredTheme = isLight ? type.options?.theme : type.options?.darkTheme
120
+ const defaultTheme = isLight ? DEFAULT_THEME : DEFAULT_DARK_THEME
121
+ return preferredTheme && SUPPORTED_THEMES.find((t) => t === preferredTheme)
122
+ ? preferredTheme
123
+ : defaultTheme
124
+ }, [type, scheme])
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: InputProps) => {
252
+ return (
253
+ <Select
254
+ {...(inputProps as StringInputProps)}
255
+ onChange={(e) => {
256
+ const newValue = e.currentTarget.value
257
+ inputProps.onChange(newValue ? set(newValue) : unset())
258
+ }}
259
+ >
260
+ {languages.map((lang: {title: string; value: string}) => (
261
+ <option key={lang.value} value={lang.value}>
262
+ {lang.title}
263
+ </option>
264
+ ))}
265
+ </Select>
266
+ )
267
+ },
268
+ [languages]
269
+ )
270
+
271
+ const renderCodeInput = useCallback(
272
+ (inputProps) => {
273
+ return (
274
+ <EditorContainer radius={1} shadow={1} readOnly={readOnly}>
275
+ <AceEditor
276
+ ref={aceEditorRef}
277
+ mode={mode}
278
+ theme={theme}
279
+ width="100%"
280
+ onChange={handleCodeChange}
281
+ name={inputProps.id}
282
+ value={inputProps.value}
283
+ markers={
284
+ value && value.highlightedLines
285
+ ? createHighlightMarkers(value.highlightedLines)
286
+ : undefined
287
+ }
288
+ onLoad={handleEditorLoad}
289
+ readOnly={readOnly}
290
+ tabSize={2}
291
+ wrapEnabled
292
+ setOptions={ACE_SET_OPTIONS}
293
+ editorProps={ACE_EDITOR_PROPS}
294
+ onFocus={handleCodeFocus}
295
+ onBlur={onBlur}
296
+ />
297
+ </EditorContainer>
298
+ )
299
+ },
300
+ [theme, handleCodeChange, handleCodeFocus, handleEditorLoad, mode, onBlur, readOnly, value]
301
+ )
302
+
303
+ return (
304
+ <Stack space={4}>
305
+ {languageFieldMember && (
306
+ <MemberField
307
+ member={languageFieldMember}
308
+ renderItem={renderItem}
309
+ renderField={renderField}
310
+ renderInput={renderLanguageInput}
311
+ renderPreview={renderPreview}
312
+ />
313
+ )}
314
+
315
+ {type.options?.withFilename && filenameMember && (
316
+ <MemberField
317
+ member={filenameMember}
318
+ renderItem={renderItem}
319
+ renderField={renderField}
320
+ renderInput={renderInput}
321
+ renderPreview={renderPreview}
322
+ />
323
+ )}
324
+
325
+ {codeFieldMember && (
326
+ <MemberField
327
+ member={codeFieldMember}
328
+ renderInput={renderCodeInput}
329
+ renderItem={renderItem}
330
+ renderField={renderField}
331
+ renderPreview={renderPreview}
332
+ />
333
+ )}
334
+ </Stack>
335
+ )
336
+ }
@@ -0,0 +1,88 @@
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
+ import './editorSupport'
9
+
10
+ const PreviewContainer = styled(Box)`
11
+ position: relative;
12
+ `
13
+
14
+ const PreviewInner = styled(Box)`
15
+ background-color: #272822;
16
+
17
+ .ace_editor {
18
+ box-sizing: border-box;
19
+ cursor: default;
20
+ pointer-events: none;
21
+ }
22
+
23
+ .ace_content {
24
+ box-sizing: border-box;
25
+ overflow: hidden;
26
+ }
27
+ `
28
+
29
+ export interface PreviewCodeProps {
30
+ type?: CodeInputType
31
+ value?: CodeInputValue
32
+ }
33
+
34
+ export default function PreviewCode(props: PreviewCodeProps) {
35
+ const aceEditorRef = useRef<any>()
36
+
37
+ useEffect(() => {
38
+ if (!aceEditorRef?.current) return
39
+
40
+ const editor = aceEditorRef.current?.editor
41
+
42
+ if (editor) {
43
+ // Avoid cursor and focus tracking by Ace
44
+ editor.renderer.$cursorLayer.element.style.opacity = 0
45
+ editor.textInput.getElement().disabled = true
46
+ }
47
+ }, [])
48
+
49
+ const handleEditorChange = useCallback(() => {
50
+ // do nothing when the editor changes
51
+ }, [])
52
+
53
+ const {value, type} = props
54
+ const fixedLanguage = type?.options?.language
55
+
56
+ const mode = value?.language || fixedLanguage || 'text'
57
+
58
+ return (
59
+ <PreviewContainer>
60
+ <PreviewInner padding={4}>
61
+ <AceEditor
62
+ ref={aceEditorRef}
63
+ focus={false}
64
+ mode={mode}
65
+ theme="monokai"
66
+ width="100%"
67
+ onChange={handleEditorChange}
68
+ maxLines={200}
69
+ readOnly
70
+ wrapEnabled
71
+ showPrintMargin={false}
72
+ highlightActiveLine={false}
73
+ cursorStart={-1}
74
+ value={(value && value.code) || ''}
75
+ markers={
76
+ value && value.highlightedLines
77
+ ? createHighlightMarkers(value.highlightedLines)
78
+ : undefined
79
+ }
80
+ tabSize={2}
81
+ showGutter={false}
82
+ setOptions={ACE_SET_OPTIONS}
83
+ editorProps={ACE_EDITOR_PROPS}
84
+ />
85
+ </PreviewInner>
86
+ </PreviewContainer>
87
+ )
88
+ }
package/src/config.ts ADDED
@@ -0,0 +1,46 @@
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
+ export const DEFAULT_DARK_THEME = 'monokai'
36
+
37
+ export const ACE_SET_OPTIONS = {
38
+ useSoftTabs: true,
39
+ navigateWithinSoftTabs: true /* note only supported by ace v1.2.7 or higher */,
40
+ }
41
+
42
+ export const ACE_EDITOR_PROPS = {$blockScrolling: true}
43
+
44
+ export const PATH_LANGUAGE = ['language']
45
+ export const PATH_CODE = ['code']
46
+ 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,31 @@
1
+ // NOTE: MAKE SURE THESE ALIGN WITH SUPPORTED_LANGUAGES in ./config
2
+ import './groq'
3
+
4
+ import 'ace-builds/src-noconflict/mode-batchfile'
5
+ import 'ace-builds/src-noconflict/mode-csharp'
6
+ import 'ace-builds/src-noconflict/mode-css'
7
+ import 'ace-builds/src-noconflict/mode-golang'
8
+ import 'ace-builds/src-noconflict/mode-html'
9
+ import 'ace-builds/src-noconflict/mode-java'
10
+ import 'ace-builds/src-noconflict/mode-javascript'
11
+ import 'ace-builds/src-noconflict/mode-json'
12
+ import 'ace-builds/src-noconflict/mode-jsx'
13
+ import 'ace-builds/src-noconflict/mode-markdown'
14
+ import 'ace-builds/src-noconflict/mode-mysql'
15
+ import 'ace-builds/src-noconflict/mode-php'
16
+ import 'ace-builds/src-noconflict/mode-python'
17
+ import 'ace-builds/src-noconflict/mode-ruby'
18
+ import 'ace-builds/src-noconflict/mode-sass'
19
+ import 'ace-builds/src-noconflict/mode-scss'
20
+ import 'ace-builds/src-noconflict/mode-sh'
21
+ import 'ace-builds/src-noconflict/mode-text'
22
+ import 'ace-builds/src-noconflict/mode-tsx'
23
+ import 'ace-builds/src-noconflict/mode-typescript'
24
+ import 'ace-builds/src-noconflict/mode-xml'
25
+ import 'ace-builds/src-noconflict/mode-yaml'
26
+
27
+ // Themes
28
+ import 'ace-builds/src-noconflict/theme-github'
29
+ import 'ace-builds/src-noconflict/theme-monokai'
30
+ import 'ace-builds/src-noconflict/theme-terminal'
31
+ import 'ace-builds/src-noconflict/theme-tomorrow'
@@ -0,0 +1,95 @@
1
+ import React from 'react'
2
+
3
+ export function getMedia(language?: string) {
4
+ if (language === 'jsx') {
5
+ return (
6
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
7
+ <g fill="#61DAFB">
8
+ <circle cx="64" cy="64" r="11.4" />
9
+ <path d="M107.3 45.2c-2.2-.8-4.5-1.6-6.9-2.3.6-2.4 1.1-4.8 1.5-7.1 2.1-13.2-.2-22.5-6.6-26.1-1.9-1.1-4-1.6-6.4-1.6-7 0-15.9 5.2-24.9 13.9-9-8.7-17.9-13.9-24.9-13.9-2.4 0-4.5.5-6.4 1.6-6.4 3.7-8.7 13-6.6 26.1.4 2.3.9 4.7 1.5 7.1-2.4.7-4.7 1.4-6.9 2.3C8.2 50 1.4 56.6 1.4 64s6.9 14 19.3 18.8c2.2.8 4.5 1.6 6.9 2.3-.6 2.4-1.1 4.8-1.5 7.1-2.1 13.2.2 22.5 6.6 26.1 1.9 1.1 4 1.6 6.4 1.6 7.1 0 16-5.2 24.9-13.9 9 8.7 17.9 13.9 24.9 13.9 2.4 0 4.5-.5 6.4-1.6 6.4-3.7 8.7-13 6.6-26.1-.4-2.3-.9-4.7-1.5-7.1 2.4-.7 4.7-1.4 6.9-2.3 12.5-4.8 19.3-11.4 19.3-18.8s-6.8-14-19.3-18.8zM92.5 14.7c4.1 2.4 5.5 9.8 3.8 20.3-.3 2.1-.8 4.3-1.4 6.6-5.2-1.2-10.7-2-16.5-2.5-3.4-4.8-6.9-9.1-10.4-13 7.4-7.3 14.9-12.3 21-12.3 1.3 0 2.5.3 3.5.9zM81.3 74c-1.8 3.2-3.9 6.4-6.1 9.6-3.7.3-7.4.4-11.2.4-3.9 0-7.6-.1-11.2-.4-2.2-3.2-4.2-6.4-6-9.6-1.9-3.3-3.7-6.7-5.3-10 1.6-3.3 3.4-6.7 5.3-10 1.8-3.2 3.9-6.4 6.1-9.6 3.7-.3 7.4-.4 11.2-.4 3.9 0 7.6.1 11.2.4 2.2 3.2 4.2 6.4 6 9.6 1.9 3.3 3.7 6.7 5.3 10-1.7 3.3-3.4 6.6-5.3 10zm8.3-3.3c1.5 3.5 2.7 6.9 3.8 10.3-3.4.8-7 1.4-10.8 1.9 1.2-1.9 2.5-3.9 3.6-6 1.2-2.1 2.3-4.2 3.4-6.2zM64 97.8c-2.4-2.6-4.7-5.4-6.9-8.3 2.3.1 4.6.2 6.9.2 2.3 0 4.6-.1 6.9-.2-2.2 2.9-4.5 5.7-6.9 8.3zm-18.6-15c-3.8-.5-7.4-1.1-10.8-1.9 1.1-3.3 2.3-6.8 3.8-10.3 1.1 2 2.2 4.1 3.4 6.1 1.2 2.2 2.4 4.1 3.6 6.1zm-7-25.5c-1.5-3.5-2.7-6.9-3.8-10.3 3.4-.8 7-1.4 10.8-1.9-1.2 1.9-2.5 3.9-3.6 6-1.2 2.1-2.3 4.2-3.4 6.2zM64 30.2c2.4 2.6 4.7 5.4 6.9 8.3-2.3-.1-4.6-.2-6.9-.2-2.3 0-4.6.1-6.9.2 2.2-2.9 4.5-5.7 6.9-8.3zm22.2 21l-3.6-6c3.8.5 7.4 1.1 10.8 1.9-1.1 3.3-2.3 6.8-3.8 10.3-1.1-2.1-2.2-4.2-3.4-6.2zM31.7 35c-1.7-10.5-.3-17.9 3.8-20.3 1-.6 2.2-.9 3.5-.9 6 0 13.5 4.9 21 12.3-3.5 3.8-7 8.2-10.4 13-5.8.5-11.3 1.4-16.5 2.5-.6-2.3-1-4.5-1.4-6.6zM7 64c0-4.7 5.7-9.7 15.7-13.4 2-.8 4.2-1.5 6.4-2.1 1.6 5 3.6 10.3 6 15.6-2.4 5.3-4.5 10.5-6 15.5C15.3 75.6 7 69.6 7 64zm28.5 49.3c-4.1-2.4-5.5-9.8-3.8-20.3.3-2.1.8-4.3 1.4-6.6 5.2 1.2 10.7 2 16.5 2.5 3.4 4.8 6.9 9.1 10.4 13-7.4 7.3-14.9 12.3-21 12.3-1.3 0-2.5-.3-3.5-.9zM96.3 93c1.7 10.5.3 17.9-3.8 20.3-1 .6-2.2.9-3.5.9-6 0-13.5-4.9-21-12.3 3.5-3.8 7-8.2 10.4-13 5.8-.5 11.3-1.4 16.5-2.5.6 2.3 1 4.5 1.4 6.6zm9-15.6c-2 .8-4.2 1.5-6.4 2.1-1.6-5-3.6-10.3-6-15.6 2.4-5.3 4.5-10.5 6-15.5 13.8 4 22.1 10 22.1 15.6 0 4.7-5.8 9.7-15.7 13.4z" />
10
+ </g>
11
+ </svg>
12
+ )
13
+ }
14
+
15
+ if (language === 'javascript') {
16
+ return (
17
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
18
+ <path fill="#F0DB4F" d="M1.408 1.408h125.184v125.185H1.408z" />
19
+ <path
20
+ fill="#323330"
21
+ d="M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zM69.462 58.943H57.753l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z"
22
+ />
23
+ </svg>
24
+ )
25
+ }
26
+
27
+ if (language === 'php') {
28
+ return (
29
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 400">
30
+ <g transform="translate(-44.632 -141.55)">
31
+ <g transform="matrix(8.3528 0 0 8.3119 -727.13 -3759.5)">
32
+ <path d="m99.974 479.48h14.204c4.1693 0.0354 7.1903 1.2367 9.063 3.604 1.8726 2.3674 2.491 5.6004 1.855 9.699-0.24737 1.8727-0.79504 3.71-1.643 5.512-0.8127 1.802-1.9434 3.4273-3.392 4.876-1.7667 1.8373-3.657 3.0033-5.671 3.498-2.014 0.49467-4.0987 0.742-6.254 0.742h-6.36l-2.014 10.07h-7.367l7.579-38.001m6.201 6.042-3.18 15.9c0.21198 0.0353 0.42398 0.053 0.636 0.053h0.742c3.392 0.0353 6.2186-0.30033 8.48-1.007 2.2613-0.74199 3.7806-3.3213 4.558-7.738 0.63597-3.71-0.00003-5.8476-1.908-6.413-1.8727-0.56531-4.2224-0.83031-7.049-0.795-0.42402 0.0353-0.83035 0.053-1.219 0.053-0.35335 0.00002-0.72435 0.00002-1.113 0l0.053-0.053" />
33
+ <path d="m133.49 469.36h7.314l-2.067 10.123h6.572c3.604 0.0707 6.2893 0.81269 8.056 2.226 1.802 1.4134 2.332 4.0987 1.59 8.056l-3.551 17.649h-7.42l3.392-16.854c0.35328-1.7666 0.2473-3.021-0.318-3.763-0.56536-0.74198-1.7844-1.113-3.657-1.113l-5.883-0.053-4.346 21.783h-7.314l7.632-38.054" />
34
+ <path d="m162.81 479.48h14.204c4.1693 0.0354 7.1903 1.2367 9.063 3.604 1.8726 2.3674 2.491 5.6004 1.855 9.699-0.24737 1.8727-0.79503 3.71-1.643 5.512-0.8127 1.802-1.9434 3.4273-3.392 4.876-1.7667 1.8373-3.657 3.0033-5.671 3.498-2.014 0.49467-4.0987 0.742-6.254 0.742h-6.36l-2.014 10.07h-7.367l7.579-38.001m6.201 6.042-3.18 15.9c0.21199 0.0353 0.42399 0.053 0.636 0.053h0.742c3.392 0.0353 6.2186-0.30033 8.48-1.007 2.2613-0.74199 3.7806-3.3213 4.558-7.738 0.63597-3.71-0.00003-5.8476-1.908-6.413-1.8727-0.56531-4.2224-0.83031-7.049-0.795-0.42402 0.0353-0.83035 0.053-1.219 0.053-0.35335 0.00002-0.72435 0.00002-1.113 0l0.053-0.053" />
35
+ </g>
36
+ </g>
37
+ </svg>
38
+ )
39
+ }
40
+
41
+ if (language === 'json') {
42
+ return (
43
+ <svg
44
+ xmlns="http://www.w3.org/2000/svg"
45
+ xmlnsXlink="http://www.w3.org/1999/xlink"
46
+ viewBox="0 0 160 160"
47
+ >
48
+ <defs>
49
+ <linearGradient id="a">
50
+ <stop offset="0" />
51
+ <stop offset="1" stopColor="#fff" />
52
+ </linearGradient>
53
+ <linearGradient
54
+ x1="-553.27"
55
+ y1="525.908"
56
+ x2="-666.116"
57
+ y2="413.045"
58
+ id="c"
59
+ xlinkHref="#a"
60
+ gradientUnits="userSpaceOnUse"
61
+ gradientTransform="matrix(.99884 0 0 .9987 689.008 -388.844)"
62
+ />
63
+ <linearGradient
64
+ x1="-666.117"
65
+ y1="413.045"
66
+ x2="-553.27"
67
+ y2="525.908"
68
+ id="b"
69
+ xlinkHref="#a"
70
+ gradientUnits="userSpaceOnUse"
71
+ gradientTransform="matrix(.99884 0 0 .9987 689.008 -388.844)"
72
+ />
73
+ </defs>
74
+ <path
75
+ d="M79.865 119.1c35.397 48.255 70.04-13.469 69.988-50.587-.06-43.886-44.54-68.414-70.017-68.414C38.943.1 0 33.895 0 80.135 0 131.531 44.64 160 79.836 160c-7.965-1.147-34.507-6.834-34.863-67.967-.24-41.346 13.487-57.865 34.805-50.599.477.177 23.514 9.265 23.514 38.95 0 29.56-23.427 38.716-23.427 38.716z"
76
+ style={{marker: 'none'}}
77
+ color="#000"
78
+ fill="url(#b)"
79
+ fillRule="evenodd"
80
+ overflow="visible"
81
+ />
82
+ <path
83
+ d="M79.823 41.4C56.433 33.34 27.78 52.618 27.78 91.23c0 63.048 46.72 68.77 52.384 68.77C121.057 160 160 126.204 160 79.964 160 28.568 115.36.1 80.164.1c9.749-1.35 52.541 10.55 52.541 69.037 0 38.141-31.953 58.905-52.735 50.033-.478-.177-23.514-9.264-23.514-38.95 0-29.56 23.367-38.818 23.367-38.818z"
84
+ style={{marker: 'none'}}
85
+ color="#000"
86
+ fill="url(#c)"
87
+ fillRule="evenodd"
88
+ overflow="visible"
89
+ />
90
+ </svg>
91
+ )
92
+ }
93
+
94
+ return undefined
95
+ }