diff --git a/.eslintrc.json b/.eslintrc.json index 5cd581ea120..76b2e6df3bf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,6 +6,8 @@ "jest": true }, "extends": [ + // extend from react-scripts config + "react-app", "plugin:react/recommended", "standard", "plugin:import/typescript" @@ -165,19 +167,6 @@ "fp/no-this": 2, "fp/no-valueof-field": 2, - // react - "react/jsx-curly-spacing": 2, - "react/jsx-equals-spacing": 2, - "react/jsx-tag-spacing": [ - 2, - { - "beforeSelfClosing": "allow" - } - ], - "react/no-children-prop": 0, - "react/no-unescaped-entities": 0, - "react/prop-types": 0, - // jsdoc "jsdoc/check-alignment": 2, "jsdoc/check-indentation": 2, @@ -208,6 +197,25 @@ "ClassExpression": true } } - ] + ], + + // jrx-a11y + "jsx-a11y/anchor-is-valid": 0, + + // react + "react/jsx-curly-spacing": 2, + "react/jsx-equals-spacing": 2, + "react/jsx-tag-spacing": [ + 2, + { + "beforeSelfClosing": "allow" + } + ], + "react/no-children-prop": 0, + "react/no-unescaped-entities": 0, + "react/prop-types": 0, + + // react-hooks + "react-hooks/exhaustive-deps": 0 } } diff --git a/src/components/ContentEditable.tsx b/src/components/ContentEditable.tsx index 6a59a9d3d46..88847db21bd 100644 --- a/src/components/ContentEditable.tsx +++ b/src/components/ContentEditable.tsx @@ -14,7 +14,8 @@ interface ContentEditableProps extends React.HTMLProps{ * Content Editable Component. */ const ContentEditable = ({ style, html, disabled, innerRef, forceUpdate, ...props }: ContentEditableProps) => { - const contentRef = innerRef || useRef(null) + const newContentRef = useRef(null) + const contentRef = innerRef || newContentRef const prevHtmlRef = useRef(html) const allowInnerHTMLChange = useRef(true) diff --git a/src/components/Note.tsx b/src/components/Note.tsx index 3bb780b2238..71e10f9982c 100644 --- a/src/components/Note.tsx +++ b/src/components/Note.tsx @@ -20,13 +20,13 @@ const editableOfNote = (noteEl: HTMLElement) => const Note = ({ context, onFocus }: NoteProps) => { const state = store.getState() - const hasNote = hasChild(state, context, '=note') - - if (!hasNote || isContextViewActive(state, context)) return null - const dispatch = useDispatch() const noteRef: { current: HTMLElement | null } = useRef(null) const [justPasted, setJustPasted] = useState(false) + + const hasNote = hasChild(state, context, '=note') + if (!hasNote || isContextViewActive(state, context)) return null + const note = attribute(state, context, '=note') /** Handles note keyboard shortcuts. */ diff --git a/src/data-providers/data-helpers/getDescendantThoughts.ts b/src/data-providers/data-helpers/getDescendantThoughts.ts index 693f82c7a6d..3166f71de49 100644 --- a/src/data-providers/data-helpers/getDescendantThoughts.ts +++ b/src/data-providers/data-helpers/getDescendantThoughts.ts @@ -43,6 +43,7 @@ async function* getDescendantThoughts(provider: DataProvider, context: Context, const contextIds = contexts.map(cx => hashContext(cx)) const providerParents = (await provider.getContextsByIds(contextIds)) + // eslint-disable-next-line no-loop-func .map((parent, i) => parent || { id: hashContext(contexts[i]), context: contexts[i], diff --git a/src/reducers/__tests__/archiveThought.js b/src/reducers/__tests__/archiveThought.js index dc5934377da..5c66d2b2a28 100644 --- a/src/reducers/__tests__/archiveThought.js +++ b/src/reducers/__tests__/archiveThought.js @@ -260,7 +260,7 @@ it('empty thought should be archived if it has descendants', () => { expect(exported).toBe(`- ${ROOT_TOKEN} - =archive - -${' '} + - ${''/* prevent trim_trailing_whitespace */} - b - a`) diff --git a/src/reducers/__tests__/deleteEmptyThought.js b/src/reducers/__tests__/deleteEmptyThought.js index 4b8cee677de..3a6ae4879f5 100644 --- a/src/reducers/__tests__/deleteEmptyThought.js +++ b/src/reducers/__tests__/deleteEmptyThought.js @@ -59,7 +59,7 @@ it('do not delete thought with children', () => { const exported = exportContext(stateNew, [ROOT_TOKEN], 'text/plain') expect(exported).toBe(`- ${ROOT_TOKEN} - -${' '} + - ${''/* prevent trim_trailing_whitespace */} - 1`) }) diff --git a/src/reducers/__tests__/subCategorizeAll.js b/src/reducers/__tests__/subCategorizeAll.js index 0120255c3ae..7c55fdb4a38 100644 --- a/src/reducers/__tests__/subCategorizeAll.js +++ b/src/reducers/__tests__/subCategorizeAll.js @@ -24,7 +24,7 @@ it('subcategorize multiple thoughts', () => { expect(exported).toBe(`- ${ROOT_TOKEN} - a - -${' '} + - ${''/* prevent trim_trailing_whitespace */} - b - c`) @@ -44,7 +44,7 @@ it('subcategorize multiple thoughts in the root', () => { const exported = exportContext(stateNew, [ROOT_TOKEN], 'text/plain') expect(exported).toBe(`- ${ROOT_TOKEN} - -${' '} + - ${''/* prevent trim_trailing_whitespace */} - a - b`) diff --git a/src/reducers/__tests__/subCategorizeOne.js b/src/reducers/__tests__/subCategorizeOne.js index 55a99a8b62d..76951fe0a48 100644 --- a/src/reducers/__tests__/subCategorizeOne.js +++ b/src/reducers/__tests__/subCategorizeOne.js @@ -22,7 +22,7 @@ it('subcategorize a thought', () => { expect(exported).toBe(`- ${ROOT_TOKEN} - a - -${' '} + - ${''/* prevent trim_trailing_whitespace */} - b`) }) @@ -39,7 +39,7 @@ it('subcategorize a thought in the root', () => { const exported = exportContext(stateNew, [ROOT_TOKEN], 'text/plain') expect(exported).toBe(`- ${ROOT_TOKEN} - -${' '} + - ${''/* prevent trim_trailing_whitespace */} - a`) }) diff --git a/src/shortcuts.ts b/src/shortcuts.ts index 434530a69ed..1108f0ba8a4 100644 --- a/src/shortcuts.ts +++ b/src/shortcuts.ts @@ -199,7 +199,7 @@ export const formatKeyboardShortcut = (keyboardOrString: Key | string) => { const keyboard = typeof keyboardOrString === 'string' ? { key: keyboardOrString as string } : keyboardOrString - return (keyboard?.alt ? 'Alt' + ' + ' : '') + + return (keyboard?.alt ? 'Alt + ' : '') + (keyboard.meta ? (isMac ? 'Command' : 'Ctrl') + ' + ' : '') + (keyboard.control ? 'Control + ' : '') + (keyboard.option ? 'Option + ' : '') + diff --git a/src/shortcuts/__tests__/newThoughtOrOutdent.ts b/src/shortcuts/__tests__/newThoughtOrOutdent.ts index 34612286158..10d2e4de26a 100644 --- a/src/shortcuts/__tests__/newThoughtOrOutdent.ts +++ b/src/shortcuts/__tests__/newThoughtOrOutdent.ts @@ -52,7 +52,7 @@ it('empty thought should outdent when hit enter', async () => { - d - e - f - -${' '}` + - ` expect(exported).toEqual(expectedOutput) }) diff --git a/src/util/__tests__/importHtml.ts b/src/util/__tests__/importHtml.ts index 1d9a788c5df..67452ce44a2 100644 --- a/src/util/__tests__/importHtml.ts +++ b/src/util/__tests__/importHtml.ts @@ -146,7 +146,7 @@ it('empty thought with nested li\'s', () => { `)) .toBe(` -- ` + ` +- ${''/* prevent trim_trailing_whitespace */} - x - y `) @@ -280,7 +280,7 @@ it('blank thoughts with subthoughts', () => { - 7/27 - 7/21 - 7/17 - - ` /* prevent trim_trailing_whitespace */ + ` + - ${''/* prevent trim_trailing_whitespace */} - Integral Living Room - Maitri 5 - DevCon