Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/payload/src/fields/validations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export const textarea: TextareaFieldValidation = (
export type CodeFieldValidation = Validate<string, unknown, unknown, CodeField>

export const code: CodeFieldValidation = (value, { req: { t }, required }) => {
if (required && value === undefined) {
if (required && (!value || (typeof value === 'string' && value.length === 0))) {
return t('validation:required')
}

Expand Down
32 changes: 30 additions & 2 deletions packages/ui/src/elements/CodeEditor/CodeEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
'use client'
import type { Monaco } from '@monaco-editor/react'

import EditorImport from '@monaco-editor/react'
import React, { useState } from 'react'

Expand All @@ -7,12 +9,37 @@ import type { Props } from './types.js'
import { useTheme } from '../../providers/Theme/index.js'
import { ShimmerEffect } from '../ShimmerEffect/index.js'
import { defaultGlobalEditorOptions, defaultOptions } from './constants.js'
import './index.scss'
import './index.css'

const Editor = 'default' in EditorImport ? EditorImport.default : EditorImport

const baseClass = 'code-editor'

function definePayloadThemes(monaco: Monaco) {
monaco.editor.defineTheme('payload-light', {
base: 'vs',
colors: {
'editor.background': '#00000000',
'editor.lineHighlightBackground': '#00000000',
'editor.lineHighlightBorder': '#00000000',
'editorGutter.background': '#00000000',
},
inherit: true,
rules: [],
})
monaco.editor.defineTheme('payload-dark', {
base: 'vs-dark',
colors: {
'editor.background': '#00000000',
'editor.lineHighlightBackground': '#00000000',
'editor.lineHighlightBorder': '#00000000',
'editorGutter.background': '#00000000',
},
inherit: true,
rules: [],
})
}

const CodeEditor: React.FC<Props> = (props) => {
const {
className,
Expand Down Expand Up @@ -58,6 +85,7 @@ const CodeEditor: React.FC<Props> = (props) => {

return (
<Editor
beforeMount={definePayloadThemes}
className={classes}
height={maxHeight ? Math.min(dynamicHeight, maxHeight) : dynamicHeight}
loading={<ShimmerEffect height={dynamicHeight} />}
Expand All @@ -76,7 +104,7 @@ const CodeEditor: React.FC<Props> = (props) => {
tabSize: undefined,
trimAutoWhitespace: undefined,
}}
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
theme={theme === 'dark' ? 'payload-dark' : 'payload-light'}
value={value}
{...rest}
// Since we are not building an IDE and the container
Expand Down
50 changes: 50 additions & 0 deletions packages/ui/src/elements/CodeEditor/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@layer payload-default {
.code-editor {
/* Base styles */
direction: ltr;
width: 100%;
height: auto;
padding: var(--spacer-2) 0;
overflow: clip;
-webkit-appearance: none;

/* Theme */
background: var(--bg-default-secondary);
border: 1px solid var(--border-default-default);
border-radius: var(--radius-medium);
box-shadow: none;

/* Typography */
font-family: var(--font-mono);
font-size: var(--text-body);
color: var(--text-default-primary);

/* Transitions */
transition-property: border, box-shadow, background-color;
transition-duration: 100ms, 100ms, 500ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);

&:focus-within {
border-color: var(--border-selected-strong);
}

&.read-only {
background: var(--bg-default-default);
border-color: var(--border-default-default);
}

/* Monaco editor resets */
.monaco-editor {
.view-overlays .current-line {
max-width: calc(100% - 14px);
border: none;
}

&:focus-within {
.view-overlays .current-line {
border: none;
}
}
}
}
}
24 changes: 0 additions & 24 deletions packages/ui/src/elements/CodeEditor/index.scss

This file was deleted.

36 changes: 21 additions & 15 deletions packages/ui/src/fields/Code/index.css
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
@layer payload-default {
.code-field {
position: relative;
display: flex;
flex-direction: column;
gap: var(--spacer-2);

&.error {
textarea {
border: 1px solid var(--border-danger-strong) !important;
}
& .code-editor {
background: var(--bg-default-secondary);
border: 1px solid var(--border-default-default);
border-radius: var(--radius-medium);
padding: var(--spacer-2) 0;
overflow: clip;
box-shadow: none;

.code-editor {
border-color: var(--border-danger-strong);
&:hover {
border-color: var(--border-default-default);
}

.monaco-editor-background,
.margin {
background-color: var(--bg-danger-tertiary);
&:focus-within {
border-color: var(--border-selected-strong);
}
}

.read-only {
.code-editor {
background: var(--bg-disabled-default);
color: var(--text-disabled-default);
box-shadow: none;
}
&.error .code-editor {
border-color: var(--border-danger-strong);
}

&.read-only .code-editor {
background: var(--bg-default-default);
border-color: var(--border-default-default);
}
}
}
2 changes: 1 addition & 1 deletion packages/ui/src/fields/FieldLabel/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
display: flex;
color: var(--text-default);
font-family: var(--text-body-medium-font-family);
font-weight: var(--text-body-medium-font-weight);
font-weight: var(--text-body-medium-strong-font-weight);

html:not([dir='RTL']) & {
margin-right: auto;
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/src/fields/JSON/index.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
@layer payload-default {
.json-field {
position: relative;
display: flex;
flex-direction: column;
gap: var(--spacer-2);

&.error {
.code-editor {
border-color: var(--border-danger-strong);

&:focus-within {
border-color: var(--border-selected-strong);
}
}

.monaco-editor-background,
Expand Down
23 changes: 23 additions & 0 deletions test/v4/collections/Code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const CodeFields: CollectionConfig = {
name: 'javascript',
type: 'code',
label: 'JavaScript',
required: true,
admin: {
language: 'javascript',
description: 'Write JavaScript code',
Expand Down Expand Up @@ -41,6 +42,28 @@ const CodeFields: CollectionConfig = {
description: 'Write TypeScript code',
},
},
{
name: 'readOnly',
type: 'code',
label: 'Read Only',
admin: {
language: 'javascript',
description: 'This field is read only',
readOnly: true,
},
defaultValue: 'const example = "read only";',
},
{
name: 'disabled',
type: 'code',
label: 'Disabled',
admin: {
language: 'javascript',
description: 'This field is disabled',
disabled: true,
},
defaultValue: 'const example = "disabled";',
},
],
}

Expand Down
24 changes: 22 additions & 2 deletions test/v4/collections/JSON/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,31 @@ const JSONFields: CollectionConfig = {
{
name: 'jsonRequired',
type: 'json',
label: 'JSON Data',
label: 'JSON Required',
required: true,
admin: {
description: 'Enter valid JSON data',
description: 'This field is required',
},
},
{
name: 'jsonReadOnly',
type: 'json',
label: 'JSON Read Only',
admin: {
description: 'This field is read only',
readOnly: true,
},
defaultValue: { example: 'read only' },
},
{
name: 'jsonDisabled',
type: 'json',
label: 'JSON Disabled',
admin: {
description: 'This field is disabled',
disabled: true,
},
defaultValue: { example: 'disabled' },
},
],
}
Expand Down
Loading