diff --git a/.changeset/blue-dancers-dream.md b/.changeset/blue-dancers-dream.md new file mode 100644 index 0000000000..7096002986 --- /dev/null +++ b/.changeset/blue-dancers-dream.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-selection': patch +--- + +Fix multi-block deletion, cmd+a while selecting, arrow up/down while selecting all diff --git a/.changeset/funny-ducks-care.md b/.changeset/funny-ducks-care.md new file mode 100644 index 0000000000..05a0ead9e7 --- /dev/null +++ b/.changeset/funny-ducks-care.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-code-block': patch +--- + +Support invalid languages diff --git a/.changeset/honest-colts-fly.md b/.changeset/honest-colts-fly.md new file mode 100644 index 0000000000..066afd2e49 --- /dev/null +++ b/.changeset/honest-colts-fly.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-core': patch +--- + +Better error message for editor.api.debug.error diff --git a/apps/www/content/docs/en/components/changelog.mdx b/apps/www/content/docs/en/components/changelog.mdx index 86bb53a0bc..734c3e6f76 100644 --- a/apps/www/content/docs/en/components/changelog.mdx +++ b/apps/www/content/docs/en/components/changelog.mdx @@ -23,7 +23,7 @@ Plate 46 - new code block - `code-syntax-leaf-static`, `code-syntax-leaf`: Updated to use lowlight token classes - Removed `prismjs` dependency and related styles - Use `lowlight` plugin option instead of `prism` option - - `code-block-combobox`: add `Auto` language option + - `code-block-combobox`: add `Auto` language option, change language values to match lowlight - `autoformat-plugin`: prevent autoformat on code blocks ```tsx diff --git a/apps/www/public/r/styles/default/code-block-element.json b/apps/www/public/r/styles/default/code-block-element.json index 2141400a1e..5cf48e8d7b 100644 --- a/apps/www/public/r/styles/default/code-block-element.json +++ b/apps/www/public/r/styles/default/code-block-element.json @@ -32,7 +32,7 @@ }, { "path": "plate-ui/code-block-combobox.tsx", - "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport type { TCodeBlockElement } from '@udecode/plate-code-block';\n\nimport { cn } from '@udecode/cn';\nimport { useEditorRef, useElement, useReadOnly } from '@udecode/plate/react';\nimport { Check } from 'lucide-react';\n\nimport { Button } from './button';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\n\nconst languages: { label: string; value: string }[] = [\n { label: 'Auto', value: 'auto' },\n { label: 'Plain Text', value: 'plaintext' },\n { label: 'Bash', value: 'bash' },\n { label: 'C', value: 'c' },\n { label: 'C++', value: 'cpp' },\n { label: 'C#', value: 'csharp' },\n { label: 'CSS', value: 'css' },\n { label: 'Diff', value: 'diff' },\n { label: 'Go', value: 'go' },\n { label: 'GraphQL', value: 'graphql' },\n { label: 'HTML', value: 'html' },\n { label: 'Java', value: 'java' },\n { label: 'JavaScript', value: 'javascript' },\n { label: 'JSON', value: 'json' },\n { label: 'JSX', value: 'jsx' },\n { label: 'Kotlin', value: 'kotlin' },\n { label: 'Less', value: 'less' },\n { label: 'Lua', value: 'lua' },\n { label: 'Makefile', value: 'makefile' },\n { label: 'Markdown', value: 'markdown' },\n { label: 'Objective-C', value: 'objectivec' },\n { label: 'PHP', value: 'php' },\n { label: 'Python', value: 'python' },\n { label: 'R', value: 'r' },\n { label: 'Ruby', value: 'ruby' },\n { label: 'Rust', value: 'rust' },\n { label: 'SCSS', value: 'scss' },\n { label: 'Shell', value: 'shell' },\n { label: 'SQL', value: 'sql' },\n { label: 'Swift', value: 'swift' },\n { label: 'TypeScript', value: 'typescript' },\n { label: 'TSX', value: 'tsx' },\n { label: 'XML', value: 'xml' },\n { label: 'YAML', value: 'yaml' },\n];\n\nexport function CodeBlockCombobox() {\n const [open, setOpen] = useState(false);\n const readOnly = useReadOnly();\n const editor = useEditorRef();\n const element = useElement();\n const value = element.lang ?? 'plaintext';\n const [searchValue, setSearchValue] = React.useState('');\n\n const items = React.useMemo(\n () =>\n languages.filter(\n (language) =>\n !searchValue ||\n language.label.toLowerCase().includes(searchValue.toLowerCase())\n ),\n [searchValue]\n );\n\n if (readOnly) return null;\n\n return (\n \n \n \n {languages.find((language) => language.value === value)?.label ??\n 'Plain Text'}\n \n \n setSearchValue('')}\n >\n \n setSearchValue(value)}\n placeholder=\"Search language...\"\n />\n No language found.\n\n \n \n {items.map((language) => (\n {\n editor.tf.setNodes(\n { lang: value },\n { at: element }\n );\n setSearchValue(value);\n setOpen(false);\n }}\n >\n \n {language.label}\n \n ))}\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport type { TCodeBlockElement } from '@udecode/plate-code-block';\n\nimport { cn } from '@udecode/cn';\nimport { useEditorRef, useElement, useReadOnly } from '@udecode/plate/react';\nimport { Check } from 'lucide-react';\n\nimport { Button } from './button';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\n\nconst languages: { label: string; value: string }[] = [\n { label: 'Auto', value: 'auto' },\n { label: 'Plain Text', value: 'plaintext' },\n { label: 'ABAP', value: 'abap' },\n { label: 'Agda', value: 'agda' },\n { label: 'Arduino', value: 'arduino' },\n { label: 'ASCII Art', value: 'ascii' },\n { label: 'Assembly', value: 'x86asm' },\n { label: 'Bash', value: 'bash' },\n { label: 'BASIC', value: 'basic' },\n { label: 'BNF', value: 'bnf' },\n { label: 'C', value: 'c' },\n { label: 'C#', value: 'csharp' },\n { label: 'C++', value: 'cpp' },\n { label: 'Clojure', value: 'clojure' },\n { label: 'CoffeeScript', value: 'coffeescript' },\n { label: 'Coq', value: 'coq' },\n { label: 'CSS', value: 'css' },\n { label: 'Dart', value: 'dart' },\n { label: 'Dhall', value: 'dhall' },\n { label: 'Diff', value: 'diff' },\n { label: 'Docker', value: 'dockerfile' },\n { label: 'EBNF', value: 'ebnf' },\n { label: 'Elixir', value: 'elixir' },\n { label: 'Elm', value: 'elm' },\n { label: 'Erlang', value: 'erlang' },\n { label: 'F#', value: 'fsharp' },\n { label: 'Flow', value: 'flow' },\n { label: 'Fortran', value: 'fortran' },\n { label: 'Gherkin', value: 'gherkin' },\n { label: 'GLSL', value: 'glsl' },\n { label: 'Go', value: 'go' },\n { label: 'GraphQL', value: 'graphql' },\n { label: 'Groovy', value: 'groovy' },\n { label: 'Haskell', value: 'haskell' },\n { label: 'HCL', value: 'hcl' },\n { label: 'HTML', value: 'html' },\n { label: 'Idris', value: 'idris' },\n { label: 'Java', value: 'java' },\n { label: 'JavaScript', value: 'javascript' },\n { label: 'JSON', value: 'json' },\n { label: 'Julia', value: 'julia' },\n { label: 'Kotlin', value: 'kotlin' },\n { label: 'LaTeX', value: 'latex' },\n { label: 'Less', value: 'less' },\n { label: 'Lisp', value: 'lisp' },\n { label: 'LiveScript', value: 'livescript' },\n { label: 'LLVM IR', value: 'llvm' },\n { label: 'Lua', value: 'lua' },\n { label: 'Makefile', value: 'makefile' },\n { label: 'Markdown', value: 'markdown' },\n { label: 'Markup', value: 'markup' },\n { label: 'MATLAB', value: 'matlab' },\n { label: 'Mathematica', value: 'mathematica' },\n { label: 'Mermaid', value: 'mermaid' },\n { label: 'Nix', value: 'nix' },\n { label: 'Notion Formula', value: 'notion' },\n { label: 'Objective-C', value: 'objectivec' },\n { label: 'OCaml', value: 'ocaml' },\n { label: 'Pascal', value: 'pascal' },\n { label: 'Perl', value: 'perl' },\n { label: 'PHP', value: 'php' },\n { label: 'PowerShell', value: 'powershell' },\n { label: 'Prolog', value: 'prolog' },\n { label: 'Protocol Buffers', value: 'protobuf' },\n { label: 'PureScript', value: 'purescript' },\n { label: 'Python', value: 'python' },\n { label: 'R', value: 'r' },\n { label: 'Racket', value: 'racket' },\n { label: 'Reason', value: 'reasonml' },\n { label: 'Ruby', value: 'ruby' },\n { label: 'Rust', value: 'rust' },\n { label: 'Sass', value: 'scss' },\n { label: 'Scala', value: 'scala' },\n { label: 'Scheme', value: 'scheme' },\n { label: 'SCSS', value: 'scss' },\n { label: 'Shell', value: 'shell' },\n { label: 'Smalltalk', value: 'smalltalk' },\n { label: 'Solidity', value: 'solidity' },\n { label: 'SQL', value: 'sql' },\n { label: 'Swift', value: 'swift' },\n { label: 'TOML', value: 'toml' },\n { label: 'TypeScript', value: 'typescript' },\n { label: 'VB.Net', value: 'vbnet' },\n { label: 'Verilog', value: 'verilog' },\n { label: 'VHDL', value: 'vhdl' },\n { label: 'Visual Basic', value: 'vbnet' },\n { label: 'WebAssembly', value: 'wasm' },\n { label: 'XML', value: 'xml' },\n { label: 'YAML', value: 'yaml' },\n];\n\nexport function CodeBlockCombobox() {\n const [open, setOpen] = useState(false);\n const readOnly = useReadOnly();\n const editor = useEditorRef();\n const element = useElement();\n const value = element.lang || 'plaintext';\n const [searchValue, setSearchValue] = React.useState('');\n\n const items = React.useMemo(\n () =>\n languages.filter(\n (language) =>\n !searchValue ||\n language.label.toLowerCase().includes(searchValue.toLowerCase())\n ),\n [searchValue]\n );\n\n if (readOnly) return null;\n\n return (\n \n \n \n {languages.find((language) => language.value === value)?.label ??\n 'Plain Text'}\n \n \n setSearchValue('')}\n >\n \n setSearchValue(value)}\n placeholder=\"Search language...\"\n />\n No language found.\n\n \n \n {items.map((language) => (\n {\n editor.tf.setNodes(\n { lang: value },\n { at: element }\n );\n setSearchValue(value);\n setOpen(false);\n }}\n >\n \n {language.label}\n \n ))}\n \n \n \n \n \n );\n}\n", "type": "registry:ui", "target": "components/plate-ui/code-block-combobox.tsx" } diff --git a/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx b/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx index b45551ead4..11c171cbac 100644 --- a/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx +++ b/apps/www/src/registry/default/plate-ui/code-block-combobox.tsx @@ -22,36 +22,91 @@ import { Popover, PopoverContent, PopoverTrigger } from './popover'; const languages: { label: string; value: string }[] = [ { label: 'Auto', value: 'auto' }, { label: 'Plain Text', value: 'plaintext' }, + { label: 'ABAP', value: 'abap' }, + { label: 'Agda', value: 'agda' }, + { label: 'Arduino', value: 'arduino' }, + { label: 'ASCII Art', value: 'ascii' }, + { label: 'Assembly', value: 'x86asm' }, { label: 'Bash', value: 'bash' }, + { label: 'BASIC', value: 'basic' }, + { label: 'BNF', value: 'bnf' }, { label: 'C', value: 'c' }, - { label: 'C++', value: 'cpp' }, { label: 'C#', value: 'csharp' }, + { label: 'C++', value: 'cpp' }, + { label: 'Clojure', value: 'clojure' }, + { label: 'CoffeeScript', value: 'coffeescript' }, + { label: 'Coq', value: 'coq' }, { label: 'CSS', value: 'css' }, + { label: 'Dart', value: 'dart' }, + { label: 'Dhall', value: 'dhall' }, { label: 'Diff', value: 'diff' }, + { label: 'Docker', value: 'dockerfile' }, + { label: 'EBNF', value: 'ebnf' }, + { label: 'Elixir', value: 'elixir' }, + { label: 'Elm', value: 'elm' }, + { label: 'Erlang', value: 'erlang' }, + { label: 'F#', value: 'fsharp' }, + { label: 'Flow', value: 'flow' }, + { label: 'Fortran', value: 'fortran' }, + { label: 'Gherkin', value: 'gherkin' }, + { label: 'GLSL', value: 'glsl' }, { label: 'Go', value: 'go' }, { label: 'GraphQL', value: 'graphql' }, + { label: 'Groovy', value: 'groovy' }, + { label: 'Haskell', value: 'haskell' }, + { label: 'HCL', value: 'hcl' }, { label: 'HTML', value: 'html' }, + { label: 'Idris', value: 'idris' }, { label: 'Java', value: 'java' }, { label: 'JavaScript', value: 'javascript' }, { label: 'JSON', value: 'json' }, - { label: 'JSX', value: 'jsx' }, + { label: 'Julia', value: 'julia' }, { label: 'Kotlin', value: 'kotlin' }, + { label: 'LaTeX', value: 'latex' }, { label: 'Less', value: 'less' }, + { label: 'Lisp', value: 'lisp' }, + { label: 'LiveScript', value: 'livescript' }, + { label: 'LLVM IR', value: 'llvm' }, { label: 'Lua', value: 'lua' }, { label: 'Makefile', value: 'makefile' }, { label: 'Markdown', value: 'markdown' }, + { label: 'Markup', value: 'markup' }, + { label: 'MATLAB', value: 'matlab' }, + { label: 'Mathematica', value: 'mathematica' }, + { label: 'Mermaid', value: 'mermaid' }, + { label: 'Nix', value: 'nix' }, + { label: 'Notion Formula', value: 'notion' }, { label: 'Objective-C', value: 'objectivec' }, + { label: 'OCaml', value: 'ocaml' }, + { label: 'Pascal', value: 'pascal' }, + { label: 'Perl', value: 'perl' }, { label: 'PHP', value: 'php' }, + { label: 'PowerShell', value: 'powershell' }, + { label: 'Prolog', value: 'prolog' }, + { label: 'Protocol Buffers', value: 'protobuf' }, + { label: 'PureScript', value: 'purescript' }, { label: 'Python', value: 'python' }, { label: 'R', value: 'r' }, + { label: 'Racket', value: 'racket' }, + { label: 'Reason', value: 'reasonml' }, { label: 'Ruby', value: 'ruby' }, { label: 'Rust', value: 'rust' }, + { label: 'Sass', value: 'scss' }, + { label: 'Scala', value: 'scala' }, + { label: 'Scheme', value: 'scheme' }, { label: 'SCSS', value: 'scss' }, { label: 'Shell', value: 'shell' }, + { label: 'Smalltalk', value: 'smalltalk' }, + { label: 'Solidity', value: 'solidity' }, { label: 'SQL', value: 'sql' }, { label: 'Swift', value: 'swift' }, + { label: 'TOML', value: 'toml' }, { label: 'TypeScript', value: 'typescript' }, - { label: 'TSX', value: 'tsx' }, + { label: 'VB.Net', value: 'vbnet' }, + { label: 'Verilog', value: 'verilog' }, + { label: 'VHDL', value: 'vhdl' }, + { label: 'Visual Basic', value: 'vbnet' }, + { label: 'WebAssembly', value: 'wasm' }, { label: 'XML', value: 'xml' }, { label: 'YAML', value: 'yaml' }, ]; @@ -61,7 +116,7 @@ export function CodeBlockCombobox() { const readOnly = useReadOnly(); const editor = useEditorRef(); const element = useElement(); - const value = element.lang ?? 'plaintext'; + const value = element.lang || 'plaintext'; const [searchValue, setSearchValue] = React.useState(''); const items = React.useMemo( @@ -82,7 +137,7 @@ export function CodeBlockCombobox() {