From 2055da53bac906d12ff1415e023059eb0a337800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Fern=C3=A1ndez=20de=20Alba?= Date: Wed, 27 Mar 2024 13:26:26 +0100 Subject: [PATCH] fix: Accordion is present, add JSX and TSX imports (#20) * Fix if accordion is present, add JSX and TSX imports * Remove .editorconfig * Fix linting and prettier through the code, add missing BlockFormData props --- .editorconfig | 36 ------- dockerfiles/storybook.js | 22 ++++- jest-addon.config.js | 8 +- package.json | 8 +- src/components/Blocks/Code/Data.jsx | 7 +- src/components/Blocks/Code/DefaultView.jsx | 29 ++++-- .../Blocks/Code/DefaultView.stories.jsx | 6 +- src/components/Blocks/Code/Edit.jsx | 12 ++- src/components/Blocks/Code/View.jsx | 2 +- src/components/Blocks/Code/schema.js | 20 +++- src/components/Blocks/Gist/Data.jsx | 7 +- src/components/Blocks/Gist/DefaultView.jsx | 4 +- src/components/Blocks/Gist/Edit.jsx | 7 +- src/components/Blocks/Gist/View.jsx | 10 +- src/components/Blocks/Mermaid/DefaultView.jsx | 11 ++- src/components/Blocks/Mermaid/Edit.jsx | 8 +- src/components/Editor/Editor.tsx | 94 ++++++++++++++----- src/index.js | 34 +++++-- 18 files changed, 227 insertions(+), 98 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 4e7c712..0000000 --- a/.editorconfig +++ /dev/null @@ -1,36 +0,0 @@ -# EditorConfig Configurtaion file, for more details see: -# http://EditorConfig.org -# EditorConfig is a convention description, that could be interpreted -# by multiple editors to enforce common coding conventions for specific -# file types - -# top-most EditorConfig file: -# Will ignore other EditorConfig files in Home directory or upper tree level. -root = true - - -[*] # For All Files -# Unix-style newlines with a newline ending every file -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -# Set default charset -charset = utf-8 -# Indent style default -indent_style = space -# Max Line Length - a hard line wrap, should be disabled -max_line_length = off - -[*.{py,cfg,ini}] -# 4 space indentation -indent_size = 4 - -[*.{html,dtml,pt,zpt,xml,zcml,js,jsx,tsx,json,less,css}] -# 2 space indentation -indent_size = 2 - -[{Makefile,.gitmodules}] -# Tab indentation (no size specified, but view as 4 spaces) -indent_style = tab -indent_size = unset -tab_width = unset diff --git a/dockerfiles/storybook.js b/dockerfiles/storybook.js index 37126a7..5cef161 100644 --- a/dockerfiles/storybook.js +++ b/dockerfiles/storybook.js @@ -51,7 +51,13 @@ const defaultRazzleOptions = { staticCssInDev: false, emitOnErrors: false, disableWebpackbar: false, - browserslist: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie 11', 'not dead'], + browserslist: [ + '>1%', + 'last 4 versions', + 'Firefox ESR', + 'not ie 11', + 'not dead', + ], }; module.exports = { @@ -110,7 +116,9 @@ module.exports = { // Put the SVG loader on top and prevent the asset/resource rule // from processing the app's SVGs config.module.rules.unshift(SVGLOADER); - const fileLoaderRule = config.module.rules.find((rule) => rule.test.test('.svg')); + const fileLoaderRule = config.module.rules.find((rule) => + rule.test.test('.svg'), + ); fileLoaderRule.exclude = /icons\/.*\.svg$/; config.plugins.unshift( @@ -131,7 +139,9 @@ module.exports = { }; // Addons have to be loaded with babel - const addonPaths = registry.addonNames.map((addon) => fs.realpathSync(registry.packages[addon].modulePath)); + const addonPaths = registry.addonNames.map((addon) => + fs.realpathSync(registry.packages[addon].modulePath), + ); resultConfig.module.rules[1].exclude = (input) => // exclude every input from node_modules except from @plone/volto /node_modules\/(?!(@plone\/volto)\/)/.test(input) && @@ -140,7 +150,11 @@ module.exports = { const addonExtenders = registry.getAddonExtenders().map((m) => require(m)); - const extendedConfig = addonExtenders.reduce((acc, extender) => extender.modify(acc, { target: 'web', dev: 'dev' }, config), resultConfig); + const extendedConfig = addonExtenders.reduce( + (acc, extender) => + extender.modify(acc, { target: 'web', dev: 'dev' }, config), + resultConfig, + ); // Note: we don't actually support razzle plugins, which are also a feature // of the razzle.extend.js addons file. Those features are probably diff --git a/jest-addon.config.js b/jest-addon.config.js index 9fab0f3..f66acd4 100644 --- a/jest-addon.config.js +++ b/jest-addon.config.js @@ -1,6 +1,9 @@ module.exports = { testMatch: ['**/src/addons/**/?(*.)+(spec|test).[jt]s?(x)'], - collectCoverageFrom: ['src/addons/**/src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'], + collectCoverageFrom: [ + 'src/addons/**/src/**/*.{js,jsx,ts,tsx}', + '!src/**/*.d.ts', + ], transformIgnorePatterns: ['node_modules/(?!(volto-slate|@plone/volto)/)'], moduleNameMapper: { '@plone/volto/cypress': '/node_modules/@plone/volto/cypress', @@ -9,7 +12,8 @@ module.exports = { '@package/(.*)$': '/src/$1', '@root/(.*)$': '/src/$1', '~/(.*)$': '/src/$1', - 'load-volto-addons': '/node_modules/@plone/volto/jest-addons-loader.js', + 'load-volto-addons': + '/node_modules/@plone/volto/jest-addons-loader.js', '\\.(css|less|scss|sass)$': 'identity-obj-proxy', }, transform: { diff --git a/package.json b/package.json index aa60993..901861a 100644 --- a/package.json +++ b/package.json @@ -32,19 +32,19 @@ "release-rc": "release-it --preRelease=rc" }, "peerDependencies": { - "@plone/volto": ">=17.0.0" + "@plone/volto": "^17.0.0 || ^18.0.0-alpha.0" }, "dependencies": { - "prismjs": "1.29.0", "mermaid": "10.8.0", + "prismjs": "1.29.0", "react-gist": "1.2.4" }, "devDependencies": { - "@plone/scripts": "^3.0.0", + "@babel/eslint-parser": "7.22.15", "@commitlint/cli": "^18.6.1", "@commitlint/config-conventional": "^18.6.2", + "@plone/scripts": "^3.0.0", "@release-it/conventional-changelog": "^8.0.1", - "@babel/eslint-parser": "7.22.15", "eslint": "8.49.0", "eslint-config-prettier": "9.0.0", "eslint-config-react-app": "7.0.1", diff --git a/src/components/Blocks/Code/Data.jsx b/src/components/Blocks/Code/Data.jsx index 2c957b1..6e254b8 100644 --- a/src/components/Blocks/Code/Data.jsx +++ b/src/components/Blocks/Code/Data.jsx @@ -4,7 +4,8 @@ import { codeSchema } from './schema'; import { useIntl } from 'react-intl'; const CodeBlockData = (props) => { - const { data, block, onChangeBlock } = props; + const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } = + props; const intl = useIntl(); const schema = codeSchema({ ...props, intl }); @@ -18,8 +19,12 @@ const CodeBlockData = (props) => { [id]: value, }); }} + onChangeBlock={onChangeBlock} formData={data} block={block} + blocksConfig={blocksConfig} + navRoot={navRoot} + contentType={contentType} /> ); }; diff --git a/src/components/Blocks/Code/DefaultView.jsx b/src/components/Blocks/Code/DefaultView.jsx index a6ff73b..a112238 100644 --- a/src/components/Blocks/Code/DefaultView.jsx +++ b/src/components/Blocks/Code/DefaultView.jsx @@ -1,24 +1,39 @@ import React from 'react'; import SyntaxHighlighter from '../../SyntaxHighlighter/SyntaxHighlighter'; import Caption from '../../Caption/Caption'; +import cx from 'classnames'; const CodeView = (props) => { - const { data } = props; - const { code, style, language, lineNbr, showLineNumbers, wrapLongLines } = data; + const { data, className, style } = props; + const { + code, + style: codeStyle, + language, + lineNbr, + showLineNumbers, + wrapLongLines, + } = data; const { caption_title, caption_description } = data; const styleWrap = wrapLongLines ? 'wrapLongLines' : ''; - const className = `code-block-wrapper ${style} ${styleWrap}`; + const codeClassName = `code-block-wrapper ${codeStyle} ${styleWrap}`; return ( <> {data && ( -
-
- +
+
+
)} - {caption_title && } + {caption_title && ( + + )} ); }; diff --git a/src/components/Blocks/Code/DefaultView.stories.jsx b/src/components/Blocks/Code/DefaultView.stories.jsx index 1aacca0..912561e 100644 --- a/src/components/Blocks/Code/DefaultView.stories.jsx +++ b/src/components/Blocks/Code/DefaultView.stories.jsx @@ -3,9 +3,11 @@ import React from 'react'; import CodeView from './DefaultView'; import Wrapper from '@plone/volto/storybook'; -const codePython = 'from Testing.makerequest import makerequest\nfrom zope.component.hooks import setSite\nimport transaction\n\n\napp = makerequest(app)\nsite = app.Plone\nsetSite(site)\n\n# Change admin password\nuser = "admin"\npassword = "verynotsecure"\napp.acl_users.users.updateUserPassword(user, password)\n\n\n# Persist changes\ntransaction.commit()\napp._p_jar.sync()'; +const codePython = + 'from Testing.makerequest import makerequest\nfrom zope.component.hooks import setSite\nimport transaction\n\n\napp = makerequest(app)\nsite = app.Plone\nsetSite(site)\n\n# Change admin password\nuser = "admin"\npassword = "verynotsecure"\napp.acl_users.users.updateUserPassword(user, password)\n\n\n# Persist changes\ntransaction.commit()\napp._p_jar.sync()'; -const codeLongLines = '# Code to show how wrap long lines would work\n\ntext = "This is a really, really, really, really long line including a lot of words and letters and a text that should not make any sense, but should be long, very long"\n\nprint(text)'; +const codeLongLines = + '# Code to show how wrap long lines would work\n\ntext = "This is a really, really, really, really long line including a lot of words and letters and a text that should not make any sense, but should be long, very long"\n\nprint(text)'; const StoryComponent = injectIntl(({ children, ...args }) => { const { language, style, code, showLineNumbers, wrapLongLines } = args; diff --git a/src/components/Blocks/Code/Edit.jsx b/src/components/Blocks/Code/Edit.jsx index 5b09ea9..1ba2aca 100644 --- a/src/components/Blocks/Code/Edit.jsx +++ b/src/components/Blocks/Code/Edit.jsx @@ -29,8 +29,16 @@ const CodeBlockEdit = (props) => { return (
- handleChange(code)} highlight={(code) => highlight(code, language)} padding={10} preClassName={`code-block-wrapper ${data.style} language-${data.language}`} /> - {caption_title && } + handleChange(code)} + highlight={(code) => highlight(code, language)} + padding={10} + preClassName={`code-block-wrapper ${data.style} language-${data.language}`} + /> + {caption_title && ( + + )} diff --git a/src/components/Blocks/Code/View.jsx b/src/components/Blocks/Code/View.jsx index 3b1f4f2..db57100 100644 --- a/src/components/Blocks/Code/View.jsx +++ b/src/components/Blocks/Code/View.jsx @@ -5,7 +5,7 @@ import CodeView from './DefaultView'; const CodeBlockView = (props) => { const { data } = props; - return <>{data && }; + return <>{data && }; }; export default withBlockExtensions(CodeBlockView); diff --git a/src/components/Blocks/Code/schema.js b/src/components/Blocks/Code/schema.js index 3a95453..ac0d15b 100644 --- a/src/components/Blocks/Code/schema.js +++ b/src/components/Blocks/Code/schema.js @@ -38,14 +38,18 @@ const messages = defineMessages({ }); export const codeSchema = (props) => { - const defaultLanguage = config.blocks?.blocksConfig?.codeBlock?.defaultLanguage; + const defaultLanguage = + config.blocks?.blocksConfig?.codeBlock?.defaultLanguage; const defaultStyle = config.blocks?.blocksConfig?.codeBlock?.defaultStyle; const availableLanguages = () => { const allLanguages = config.settings.codeBlock.languages || {}; - const languages = Array.from(Object.entries(allLanguages), ([key, value]) => { - return [key, value.label]; - }); + const languages = Array.from( + Object.entries(allLanguages), + ([key, value]) => { + return [key, value.label]; + }, + ); return languages; }; @@ -59,7 +63,13 @@ export const codeSchema = (props) => { { id: 'default', title: 'Default', - fields: ['language', 'style', 'showLineNumbers', 'wrapLongLines', 'lineNbr'], + fields: [ + 'language', + 'style', + 'showLineNumbers', + 'wrapLongLines', + 'lineNbr', + ], }, { id: 'caption', diff --git a/src/components/Blocks/Gist/Data.jsx b/src/components/Blocks/Gist/Data.jsx index 9408a37..6f76b46 100644 --- a/src/components/Blocks/Gist/Data.jsx +++ b/src/components/Blocks/Gist/Data.jsx @@ -4,7 +4,8 @@ import { gistSchema } from './schema'; import { useIntl } from 'react-intl'; const GistBlockData = (props) => { - const { data, block, onChangeBlock } = props; + const { block, blocksConfig, data, onChangeBlock, navRoot, contentType } = + props; const intl = useIntl(); const schema = gistSchema({ ...props, intl }); @@ -18,8 +19,12 @@ const GistBlockData = (props) => { [id]: value, }); }} + onChangeBlock={onChangeBlock} formData={data} block={block} + blocksConfig={blocksConfig} + navRoot={navRoot} + contentType={contentType} /> ); }; diff --git a/src/components/Blocks/Gist/DefaultView.jsx b/src/components/Blocks/Gist/DefaultView.jsx index 226489c..2b83914 100644 --- a/src/components/Blocks/Gist/DefaultView.jsx +++ b/src/components/Blocks/Gist/DefaultView.jsx @@ -7,7 +7,9 @@ const GistView = (props) => { return ( <> {gistId && } - {caption_title && } + {caption_title && ( + + )} ); }; diff --git a/src/components/Blocks/Gist/Edit.jsx b/src/components/Blocks/Gist/Edit.jsx index 6796727..659003b 100644 --- a/src/components/Blocks/Gist/Edit.jsx +++ b/src/components/Blocks/Gist/Edit.jsx @@ -13,7 +13,12 @@ const GistBlockEdit = (props) => { {data && ( <>
- + )} diff --git a/src/components/Blocks/Gist/View.jsx b/src/components/Blocks/Gist/View.jsx index 4b0baa9..5289b50 100644 --- a/src/components/Blocks/Gist/View.jsx +++ b/src/components/Blocks/Gist/View.jsx @@ -7,7 +7,15 @@ const GistBlockView = (props) => { const { gistId, file, caption_title, caption_description } = data; return (
- {data && } + {data && ( + + )}
); }; diff --git a/src/components/Blocks/Mermaid/DefaultView.jsx b/src/components/Blocks/Mermaid/DefaultView.jsx index 621880f..29c698e 100644 --- a/src/components/Blocks/Mermaid/DefaultView.jsx +++ b/src/components/Blocks/Mermaid/DefaultView.jsx @@ -8,7 +8,10 @@ const MermaidView = (props) => { useEffect(() => { const loadMermaid = async () => { - const config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } }; + const config = { + startOnLoad: true, + flowchart: { useMaxWidth: false, htmlLabels: true }, + }; const { default: mermaid } = await import('mermaid/dist/mermaid.esm.mjs'); setMermaid(mermaid); mermaid.initialize(config); @@ -30,7 +33,11 @@ const MermaidView = (props) => { } }, [mermaid, elementId, code]); - return
{svg &&
}
; + return ( +
+ {svg &&
} +
+ ); }; export default MermaidView; diff --git a/src/components/Blocks/Mermaid/Edit.jsx b/src/components/Blocks/Mermaid/Edit.jsx index 4f5242b..1301b07 100644 --- a/src/components/Blocks/Mermaid/Edit.jsx +++ b/src/components/Blocks/Mermaid/Edit.jsx @@ -19,7 +19,13 @@ const MermaidBlockEdit = (props) => { return (
- handleChange(code)} highlight={(code) => highlight(code, language)} padding={10} preClassName={`code-block-wrapper ${data.style} language-mermaid`} /> + handleChange(code)} + highlight={(code) => highlight(code, language)} + padding={10} + preClassName={`code-block-wrapper ${data.style} language-mermaid`} + />
); diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 16223ce..f7a38d7 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -62,8 +62,14 @@ const KEYCODE_BACK_QUOTE = 192; const HISTORY_LIMIT = 100; const HISTORY_TIME_GAP = 3000; -const isWindows = typeof window !== 'undefined' && 'navigator' in window && /Win/i.test(navigator.platform); -const isMacLike = typeof window !== 'undefined' && 'navigator' in window && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); +const isWindows = + typeof window !== 'undefined' && + 'navigator' in window && + /Win/i.test(navigator.platform); +const isMacLike = + typeof window !== 'undefined' && + 'navigator' in window && + /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); const className = 'npm__react-simple-code-editor__textarea'; @@ -124,7 +130,8 @@ export default class Editor extends React.Component { }); }; - private _getLines = (text: string, position: number) => text.substring(0, position).split('\n'); + private _getLines = (text: string, position: number) => + text.substring(0, position).split('\n'); private _recordChange = (record: Record, overwrite: boolean = false) => { const { stack, offset } = this._history; @@ -156,10 +163,14 @@ export default class Editor extends React.Component { const re = /[^a-z0-9]([a-z0-9]+)$/i; // Get the previous line - const previous = this._getLines(last.value, last.selectionStart).pop()?.match(re); + const previous = this._getLines(last.value, last.selectionStart) + .pop() + ?.match(re); // Get the current line - const current = this._getLines(record.value, record.selectionStart).pop()?.match(re); + const current = this._getLines(record.value, record.selectionStart) + .pop() + ?.match(re); if (previous?.[1] && current?.[1]?.startsWith(previous[1])) { // The last word of the previous line and current line match @@ -264,7 +275,11 @@ export default class Editor extends React.Component { const nextValue = value .split('\n') .map((line, i) => { - if (i >= startLine && i <= endLine && line.startsWith(tabCharacter)) { + if ( + i >= startLine && + i <= endLine && + line.startsWith(tabCharacter) + ) { return line.substring(tabCharacter.length); } @@ -279,7 +294,9 @@ export default class Editor extends React.Component { value: nextValue, // Move the start cursor if first line in selection was modified // It was modified only if it started with a tab - selectionStart: startLineText?.startsWith(tabCharacter) ? selectionStart - tabCharacter.length : selectionStart, + selectionStart: startLineText?.startsWith(tabCharacter) + ? selectionStart - tabCharacter.length + : selectionStart, // Move the end cursor by total number of characters removed selectionEnd: selectionEnd - (value.length - nextValue.length), }); @@ -304,16 +321,23 @@ export default class Editor extends React.Component { .join('\n'), // Move the start cursor by number of characters added in first line of selection // Don't move it if it there was no text before cursor - selectionStart: startLineText && /\S/.test(startLineText) ? selectionStart + tabCharacter.length : selectionStart, + selectionStart: + startLineText && /\S/.test(startLineText) + ? selectionStart + tabCharacter.length + : selectionStart, // Move the end cursor by total number of characters added - selectionEnd: selectionEnd + tabCharacter.length * (endLine - startLine + 1), + selectionEnd: + selectionEnd + tabCharacter.length * (endLine - startLine + 1), }); } else { const updatedSelection = selectionStart + tabCharacter.length; this._applyEdits({ // Insert tab character at caret - value: value.substring(0, selectionStart) + tabCharacter + value.substring(selectionEnd), + value: + value.substring(0, selectionStart) + + tabCharacter + + value.substring(selectionEnd), // Update caret position selectionStart: updatedSelection, selectionEnd: updatedSelection, @@ -331,7 +355,9 @@ export default class Editor extends React.Component { this._applyEdits({ // Remove tab character at caret - value: value.substring(0, selectionStart - tabCharacter.length) + value.substring(selectionEnd), + value: + value.substring(0, selectionStart - tabCharacter.length) + + value.substring(selectionEnd), // Update caret position selectionStart: updatedSelection, selectionEnd: updatedSelection, @@ -353,14 +379,22 @@ export default class Editor extends React.Component { this._applyEdits({ // Insert indentation character at caret - value: value.substring(0, selectionStart) + indent + value.substring(selectionEnd), + value: + value.substring(0, selectionStart) + + indent + + value.substring(selectionEnd), // Update caret position selectionStart: updatedSelection, selectionEnd: updatedSelection, }); } } - } else if (e.keyCode === KEYCODE_PARENS || e.keyCode === KEYCODE_BRACKETS || e.keyCode === KEYCODE_QUOTE || e.keyCode === KEYCODE_BACK_QUOTE) { + } else if ( + e.keyCode === KEYCODE_PARENS || + e.keyCode === KEYCODE_BRACKETS || + e.keyCode === KEYCODE_QUOTE || + e.keyCode === KEYCODE_BACK_QUOTE + ) { let chars; if (e.keyCode === KEYCODE_PARENS && e.shiftKey) { @@ -386,7 +420,12 @@ export default class Editor extends React.Component { e.preventDefault(); this._applyEdits({ - value: value.substring(0, selectionStart) + chars[0] + value.substring(selectionStart, selectionEnd) + chars[1] + value.substring(selectionEnd), + value: + value.substring(0, selectionStart) + + chars[0] + + value.substring(selectionStart, selectionEnd) + + chars[1] + + value.substring(selectionEnd), // Update caret position selectionStart, selectionEnd: selectionEnd + 2, @@ -409,16 +448,20 @@ export default class Editor extends React.Component { ? // Trigger redo with ⌘+Shift+Z on Mac e.metaKey && e.keyCode === KEYCODE_Z && e.shiftKey : isWindows - ? // Trigger redo with Ctrl+Y on Windows - e.ctrlKey && e.keyCode === KEYCODE_Y - : // Trigger redo with Ctrl+Shift+Z on other platforms - e.ctrlKey && e.keyCode === KEYCODE_Z && e.shiftKey) && + ? // Trigger redo with Ctrl+Y on Windows + e.ctrlKey && e.keyCode === KEYCODE_Y + : // Trigger redo with Ctrl+Shift+Z on other platforms + e.ctrlKey && e.keyCode === KEYCODE_Z && e.shiftKey) && !e.altKey ) { e.preventDefault(); this._redoEdit(); - } else if (e.keyCode === KEYCODE_M && e.ctrlKey && (isMacLike ? e.shiftKey : true)) { + } else if ( + e.keyCode === KEYCODE_M && + e.ctrlKey && + (isMacLike ? e.shiftKey : true) + ) { e.preventDefault(); // Toggle capturing tab key so users can focus away @@ -503,7 +546,14 @@ export default class Editor extends React.Component { return (
-