-
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Migrated the codebase to TypeScript. - Provided type definitions for plugin users. - Restructured folders. - Refactored and optimized the codebase. - Added the missing MaxWords option. - Updated dependencies. - Refreshed the plugin icon.
- Loading branch information
1 parent
c83d41e
commit d24d9a9
Showing
79 changed files
with
3,672 additions
and
2,000 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dist | ||
node_modules | ||
.github | ||
assets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"extends": ["airbnb", "airbnb-typescript", "airbnb/hooks", "prettier"], | ||
"plugins": ["prettier"], | ||
"parserOptions": { | ||
"project": ["./admin/tsconfig.json", "./server/tsconfig.json"] | ||
}, | ||
"rules": { | ||
"@typescript-eslint/no-use-before-define": "off", | ||
"class-methods-use-this": "off", | ||
"max-classes-per-file": "off", | ||
"import/prefer-default-export": "off", | ||
"import/no-default-export": "warn", | ||
"import/extensions": "warn", | ||
"react/require-default-props": "warn", | ||
"no-param-reassign": "warn", | ||
"react/jsx-no-bind": "warn", | ||
"no-console": ["warn", { "allow": ["warn", "error"] }] | ||
}, | ||
"overrides": [ | ||
{ | ||
"files": ["server/**/*"], | ||
"rules": { | ||
"import/no-default-export": "off" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dist | ||
node_modules | ||
.github | ||
assets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"semi": true, | ||
"singleQuote": true, | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"trailingComma": "es5", | ||
"endOfLine": "lf", | ||
"printWidth": 100, | ||
"arrowParens": "avoid", | ||
"bracketSpacing": true, | ||
"quoteProps": "as-needed", | ||
"jsxSingleQuote": false, | ||
"embeddedLanguageFormatting": "auto" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export {}; | ||
|
||
declare global { | ||
interface Window { | ||
strapi: { | ||
backendURL: string; | ||
}; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import React, { useCallback, useRef, useState } from 'react'; | ||
import { useField } from '@strapi/strapi/admin'; | ||
import { Flex } from '@strapi/design-system'; | ||
import { ClassicEditor } from 'ckeditor5'; | ||
import { CKEditor } from '@ckeditor/ckeditor5-react'; | ||
import 'ckeditor5/ckeditor5.css'; | ||
|
||
import { useEditorContext } from './EditorProvider'; | ||
import { getStoredToken } from '../utils'; | ||
import { MediaLib } from './MediaLib'; | ||
import type { | ||
StrapiMediaLibPlugin, | ||
StrapiUploadAdapterConfig, | ||
StrapiUploadAdapterPlugin, | ||
} from '../plugins'; | ||
|
||
export type WordCountPluginStats = { | ||
words: number; | ||
characters: number; | ||
}; | ||
|
||
export function CKEReact() { | ||
const [mediaLibVisible, setMediaLibVisible] = useState<boolean>(false); | ||
const [editorInstance, setEditorInstance] = useState<ClassicEditor | null>(null); | ||
|
||
const { name, disabled, error, preset, wordsLimit, charsLimit, validateInputLength } = | ||
useEditorContext(); | ||
const { onChange: fieldOnChange, value: fieldValue } = useField(name); | ||
|
||
const wordCounterRef = useRef<HTMLElement>(null); | ||
|
||
const toggleMediaLib = useCallback(() => setMediaLibVisible(prev => !prev), [setMediaLibVisible]); | ||
|
||
const handleChangeAssets = useCallback( | ||
(newElems: string): void => { | ||
if (!editorInstance) { | ||
throw new Error('CKEditor: Editor instance is not initialized'); | ||
} | ||
|
||
const viewFragment = editorInstance.data.processor.toView(newElems); | ||
const modelFragment = editorInstance.data.toModel(viewFragment); | ||
editorInstance?.model.insertContent(modelFragment); | ||
|
||
toggleMediaLib(); | ||
}, | ||
[toggleMediaLib, editorInstance] | ||
); | ||
|
||
const onEditorReady = (editor: ClassicEditor): void => { | ||
setUpPlugins(editor); | ||
setEditorInstance(editor); | ||
}; | ||
|
||
const onEditorChange = (_e: any, editor: ClassicEditor): void => { | ||
const data = editor.getData(); | ||
fieldOnChange(name, data); | ||
}; | ||
|
||
if (!preset) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<> | ||
<CKEditor | ||
editor={ClassicEditor} | ||
config={preset.editorConfig} | ||
disabled={disabled} | ||
data={fieldValue ?? ''} | ||
onReady={onEditorReady} | ||
onChange={onEditorChange} | ||
/> | ||
<Flex ref={wordCounterRef} color={error ? 'danger600' : 'neutral400'} /> | ||
<MediaLib | ||
isOpen={mediaLibVisible} | ||
toggle={toggleMediaLib} | ||
handleChangeAssets={handleChangeAssets} | ||
/> | ||
</> | ||
); | ||
|
||
function setUpPlugins(editor: ClassicEditor): void { | ||
const pluginsToSetup: Record<string, (editor: ClassicEditor) => void> = { | ||
WordCount: setUpWordCount, | ||
ImageUploadEditing: setUpImageUploadEditing, | ||
StrapiMediaLib: setUpStrapiMediaLib, | ||
StrapiUploadAdapter: setUpStrapiUploadAdapter, | ||
}; | ||
|
||
Object.entries(pluginsToSetup).forEach(([pluginName, setUpFn]) => { | ||
if (editor.plugins.has(pluginName)) { | ||
try { | ||
setUpFn(editor); | ||
} catch (err) { | ||
console.error(`CKEditor: Error setting up ${pluginName} plugin `, err); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
function setUpWordCount(editor: ClassicEditor): void { | ||
const wordCountPlugin = editor.plugins.get('WordCount'); | ||
|
||
if (wordsLimit || charsLimit) { | ||
wordCountPlugin.on('update', (_e, stats: WordCountPluginStats) => validateInputLength(stats)); | ||
} | ||
|
||
wordCounterRef.current?.appendChild(wordCountPlugin.wordCountContainer); | ||
} | ||
|
||
function setUpImageUploadEditing(editor: ClassicEditor): void { | ||
const imageUploadEditingPlugin = editor.plugins.get('ImageUploadEditing'); | ||
|
||
const setAltAttribute = (_e: any, { data, imageElement }: any) => { | ||
editor.model.change(writer => { | ||
writer.setAttribute('alt', data.alt, imageElement); | ||
}); | ||
}; | ||
|
||
imageUploadEditingPlugin.on('uploadComplete', setAltAttribute); | ||
} | ||
|
||
function setUpStrapiMediaLib(editor: ClassicEditor): void { | ||
const strapiMediaLibPlugin = editor.plugins.get('StrapiMediaLib') as StrapiMediaLibPlugin; | ||
strapiMediaLibPlugin.connect(toggleMediaLib); | ||
} | ||
|
||
function setUpStrapiUploadAdapter(editor: ClassicEditor): void { | ||
const StrapiUploadAdapterPlugin = editor.plugins.get( | ||
'StrapiUploadAdapter' | ||
) as StrapiUploadAdapterPlugin; | ||
const token = getStoredToken(); | ||
const { backendURL } = window.strapi; | ||
const config: StrapiUploadAdapterConfig = { | ||
uploadUrl: `${backendURL}/upload`, | ||
backendUrl: backendURL, | ||
headers: { Authorization: `Bearer ${token}` }, | ||
responsive: window.SH_CKE_UPLOAD_ADAPTER_IS_RESPONSIVE, | ||
}; | ||
|
||
StrapiUploadAdapterPlugin.initAdapter(config); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React from 'react'; | ||
import { styled } from 'styled-components'; | ||
import { lightTheme, Flex } from '@strapi/design-system'; | ||
|
||
export function CKEditorIcon() { | ||
return ( | ||
<IconBox justifyContent="center" alignItems="center" width={7} height={6} hasRadius aria-hidden> | ||
<SvgIcon /> | ||
</IconBox> | ||
); | ||
} | ||
|
||
function SvgIcon() { | ||
return ( | ||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-8 -7 37 37"> | ||
<path | ||
d="M15.04 16.726a3.98 3.98 0 0 0-1.535.524 3.96 3.96 0 0 0-1.402 1.364c-.108.18-.716 1.347-.716 1.347l-2.09 3.82.022.016c.097.063.2.116.308.159.317.113.65.175.987.18 1.264.058 2.529-.016 3.793-.007.725.023 1.45.005 2.172-.053.348-.017.687-.117.99-.29.31-.178.576-.423.78-.717.138-.205.283-.407.409-.62.6-1.02 1.199-2.043 1.794-3.065.187-.321.37-.644.555-.966l.281-.481c.236-.392.367-.838.381-1.294l-3.258.057s-3.147-.012-3.472.026Zm2.764.903Z" | ||
fill={lightTheme.colors.secondary700} | ||
/> | ||
<path | ||
d="m7.12 22.61 1.901-3.477.46-.877c-.31-.168-.614-.35-.918-.528-.866-.508-1.766-.957-2.613-1.498a2.459 2.459 0 0 1-.609-.517c-.27-.336-.341-.736-.362-1.15-.052-1.022-.003-2.045-.02-3.068-.01-.487 0-.975.005-1.462.01-.806.384-1.382 1.069-1.783L8.115 7.03c.55-.322 1.102-.642 1.654-.961.127-.073.263-.13.395-.192.68-.321 1.298-.119 1.9.213.039.02.075.045.112.068.306.149.605.313.895.491.794.445 1.587.893 2.378 1.343.239.139.469.292.688.458.485.36.636.875.666 1.445.039.71.017 1.422.013 2.134-.002.698.01 1.396.003 2.094 1.478-.006 3.146 0 3.146 0l1.807-.032c-.006-.73-.016-1.46-.017-2.19 0-1.31.037-2.62-.039-3.928-.061-1.05-.34-2-1.232-2.666a12.549 12.549 0 0 0-1.264-.848c-1.454-.834-2.91-1.664-4.37-2.49-.545-.308-1.067-.659-1.644-.91-.069-.043-.135-.089-.205-.128-1.106-.613-2.24-.992-3.485-.405-.242.115-.49.218-.723.352-1.011.58-2.02 1.166-3.026 1.757-1.271.744-2.54 1.488-3.81 2.234C.705 5.602.025 6.66.012 8.144c-.008.897-.02 1.794 0 2.691.039 1.884-.045 3.77.058 5.652.042.761.174 1.499.672 2.12.32.377.698.7 1.121.956 1.556 1.001 3.209 1.835 4.8 2.775l.457.271Z" | ||
fill={lightTheme.colors.secondary600} | ||
/> | ||
</svg> | ||
); | ||
} | ||
|
||
const IconBox = styled(Flex)` | ||
background-color: ${lightTheme.colors.secondary100}; | ||
border: 1px solid ${lightTheme.colors.secondary200}; | ||
`; |
Oops, something went wrong.