Skip to content

Commit

Permalink
feat: support code block language selection
Browse files Browse the repository at this point in the history
  • Loading branch information
petyosi committed Jul 3, 2023
1 parent ad70d8a commit 6dba070
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/system/EditorSystemComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export const {
editorRootElementRef: 'editorRootElementRef',
viewMode: 'viewMode',
linkAutocompleteSuggestions: 'linkAutocompleteSuggestions',
imageAutocompleteSuggestions: 'imageAutocompleteSuggestions'
imageAutocompleteSuggestions: 'imageAutocompleteSuggestions',
codeBlockLanguages: 'codeBlockLanguages'
},
events: {
onChange: 'onChange'
Expand Down
10 changes: 10 additions & 0 deletions src/system/Sandpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,18 @@ const defaultSandpackConfig: SandpackConfig = {
]
}

const defaultCodeBlockLanguages = {
js: 'JavaScript',
ts: 'TypeScript',
tsx: 'TypeScript (React)',
jsx: 'JavaScript (React)',
css: 'CSS'
}

export const [SandpackSystem] = system(
(r, [{ activeEditor, activeEditorType, createEditorSubscription }]) => {
const sandpackConfig = r.node<SandpackConfig>(defaultSandpackConfig)
const codeBlockLanguages = r.node(defaultCodeBlockLanguages)
const insertSandpack = r.node<string>()
const insertCodeBlock = r.node<true>()

Expand Down Expand Up @@ -170,6 +179,7 @@ export const [SandpackSystem] = system(
})

return {
codeBlockLanguages,
insertSandpack,
insertCodeBlock,
sandpackConfig
Expand Down
23 changes: 23 additions & 0 deletions src/ui/MDXEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,35 @@ export interface MDXEditorProps {
* The initial view mode for the editor. Defaults to `ViewMode.editor`.
*/
viewMode?: ViewMode
/**
* Triggered when the markdown content changes.
*/
onChange?: (markdown: string) => void
/**
* The CSS class name to be applied to the wrapper element of the component.
*/
className?: string
/**
* The CSS class name to be applied to the content editable element.
*/
contentEditableClassName?: string
/**
* The options to be used when parsing the markdown content.
* @see the {@link MarkdownParseOptions} interface for more details.
*/
markdownParseOptions?: Partial<MarkdownParseOptions>
/**
* The {@link https://lexical.dev/ Lexical nodes} used by the editor.
*/
lexicalNodes?: Klass<LexicalNode>[]
/**
* The options used when converting the lexical tree to markdown.
*/
lexicalConvertOptions?: Partial<ExportMarkdownFromLexicalOptions>
/**
* The supported code block languages.
*/
codeBlockLanguages?: Record<string, string>
}

const defaultNodeDecorators: NodeDecoratorComponents = {
Expand Down
15 changes: 9 additions & 6 deletions src/ui/ToolbarPlugin/CodeBlockLanguageSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { useEmitterValues } from '../../system/EditorSystemComponent'
import { $getNodeByKey } from 'lexical'
import { CodeBlockEditorType } from '../../types/ActiveEditorType'
import { CodeBlockNode } from '../../nodes'
import styles from '../styles.module.css'

export function CodeBlockLanguageSelect() {
const [activeEditorType, activeEditor] = useEmitterValues('activeEditorType', 'activeEditor')
const [activeEditorType, activeEditor, codeBlockLanguages] = useEmitterValues('activeEditorType', 'activeEditor', 'codeBlockLanguages')

const nodeLanguage = React.useMemo(() => {
let language!: string
Expand All @@ -31,11 +32,13 @@ export function CodeBlockLanguageSelect() {
})
}}
>
<SelectTrigger placeholder="Language" />
<SelectContent>
<SelectItem value="js">JavaScript</SelectItem>
<SelectItem value="ts">TypeScript</SelectItem>
<SelectItem value="css">CSS</SelectItem>
<SelectTrigger placeholder="Language" className={styles.toolbarCodeBlockLanguageSelectTrigger} />
<SelectContent className={styles.toolbarCodeBlockLanguageSelectContent}>
{Object.entries(codeBlockLanguages).map(([value, label]) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectContent>
</Select.Root>
)
Expand Down
6 changes: 3 additions & 3 deletions src/ui/ToolbarPlugin/SelectPieces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const SelectItem = React.forwardRef<HTMLDivElement | null, { className?:
}
)

export const SelectTrigger: React.FC<{ placeholder: string }> = ({ placeholder }) => {
export const SelectTrigger: React.FC<{ placeholder: string; className?: string }> = ({ placeholder, className }) => {
return (
<Select.Trigger aria-label={placeholder} className={styles.toolbarNodeKindSelectTrigger}>
<Select.Trigger aria-label={placeholder} className={classNames(styles.toolbarNodeKindSelectTrigger, className)}>
<Select.Value placeholder={placeholder} />
<Select.Icon className={styles.toolbarNodeKindSelectDropdownArrow}>
<DropDownIcon />
Expand All @@ -44,7 +44,7 @@ export const SelectContent: React.FC<{ children: React.ReactNode; className?: st
export const SelectButtonTrigger: React.FC<{ children: React.ReactNode; title: string; className?: string }> = ({
children,
title,
className,
className
}) => {
return (
<Select.Trigger className={classNames(styles.toolbarButtonSelectTrigger, className)} title={title}>
Expand Down
10 changes: 9 additions & 1 deletion src/ui/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@
}

.toolbarNodeKindSelectContainer,
.toolbarButtonDropdownContainer {
.toolbarButtonDropdownContainer,
.toolbarCodeBlockLanguageSelectContent
{
z-index: 60;
width: var(--spacing-36);
border-bottom-left-radius: var(--radius-base);
Expand Down Expand Up @@ -261,6 +263,12 @@
padding-inline-end: var(--spacing-1);
}

.toolbarCodeBlockLanguageSelectTrigger,
.toolbarCodeBlockLanguageSelectContent
{
width: var(--spacing-48);
}

.toolbarNodeKindSelectItem {
cursor: default;
display: flex;
Expand Down

0 comments on commit 6dba070

Please sign in to comment.