diff --git a/.eslintrc.js b/.eslintrc.js index 0ecb15a5b4..7cefd7347b 100644 Binary files a/.eslintrc.js and b/.eslintrc.js differ diff --git a/.stylelintrc.json b/.stylelintrc.json index c8a71a1648..1223ef3ade 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,16 +1,22 @@ { - "extends": ["stylelint-config-standard"], - "ignoreFiles": ["app/styles/reset.scss"], - "plugins": ["stylelint-scss"], + "extends": ["stylelint-config-standard-scss"], "rules": { + "alpha-value-notation": null, "at-rule-no-unknown": null, "at-rule-empty-line-before": ["always", { "ignore": ["after-comment", "first-nested", "inside-block", "blockless-after-same-name-blockless", "blockless-after-blockless"] }], + "color-function-notation": null, + "custom-property-pattern": null, + "declaration-block-no-redundant-longhand-properties": null, "declaration-colon-newline-after": null, "declaration-empty-line-before": "never", "font-family-no-missing-generic-family-keyword": [true, { "ignoreFontFamilies": ["ForkAwesome", "Font Awesome 5 Free", "OpenDyslexic", "soapbox"] }], + "max-line-length": null, "no-descending-specificity": null, "no-duplicate-selectors": null, - "scss/at-rule-no-unknown": [true, { "ignoreAtRules": ["/tailwind/", "layer"]}], - "no-invalid-position-at-import-rule": null + "no-invalid-position-at-import-rule": null, + "scss/at-rule-no-unknown": [true, { "ignoreAtRules": ["tailwind", "apply", "layer", "config"]}], + "scss/operator-no-unspaced": null, + "selector-class-pattern": null, + "string-quotes": "single" } } diff --git a/app/soapbox/components/autosuggest-input.tsx b/app/soapbox/components/autosuggest-input.tsx index fe82744c18..1228901129 100644 --- a/app/soapbox/components/autosuggest-input.tsx +++ b/app/soapbox/components/autosuggest-input.tsx @@ -46,7 +46,7 @@ export default class AutosuggestInput extends ImmutablePureComponent { return this.props.autoSelect ? 0 : -1; - } + }; state = { suggestionsHidden: true, @@ -76,7 +76,7 @@ export default class AutosuggestInput extends ImmutablePureComponent = (e) => { const { suggestions, menu, disabled } = this.props; @@ -145,15 +145,15 @@ export default class AutosuggestInput extends ImmutablePureComponent { this.setState({ suggestionsHidden: true, focused: false }); - } + }; onFocus = () => { this.setState({ focused: true }); - } + }; onSuggestionClick: React.EventHandler = (e) => { const index = Number(e.currentTarget?.getAttribute('data-index')); @@ -161,7 +161,7 @@ export default class AutosuggestInput extends ImmutablePureComponent { this.input = c; - } + }; renderSuggestion = (suggestion: AutoSuggestion, i: number) => { const { selectedSuggestion } = this.state; @@ -209,21 +209,21 @@ export default class AutosuggestInput extends ImmutablePureComponent ); - } + }; handleMenuItemAction = (item: MenuItem | null, e: React.MouseEvent | React.KeyboardEvent) => { this.onBlur(); if (item?.action) { item.action(e); } - } + }; handleMenuItemClick = (item: MenuItem | null): React.MouseEventHandler => { return e => { e.preventDefault(); this.handleMenuItemAction(item, e); }; - } + }; renderMenu = () => { const { menu, suggestions } = this.props; diff --git a/app/soapbox/components/autosuggest-textarea.tsx b/app/soapbox/components/autosuggest-textarea.tsx index b7fceb86df..b1b846c56f 100644 --- a/app/soapbox/components/autosuggest-textarea.tsx +++ b/app/soapbox/components/autosuggest-textarea.tsx @@ -64,7 +64,7 @@ class AutosuggestTextarea extends ImmutablePureComponent } this.props.onChange(e); - } + }; onKeyDown: React.KeyboardEventHandler = (e) => { const { suggestions, disabled } = this.props; @@ -122,7 +122,7 @@ class AutosuggestTextarea extends ImmutablePureComponent } this.props.onKeyDown(e); - } + }; onBlur = () => { this.setState({ suggestionsHidden: true, focused: false }); @@ -130,7 +130,7 @@ class AutosuggestTextarea extends ImmutablePureComponent if (this.props.onBlur) { this.props.onBlur(); } - } + }; onFocus = () => { this.setState({ focused: true }); @@ -138,14 +138,14 @@ class AutosuggestTextarea extends ImmutablePureComponent if (this.props.onFocus) { this.props.onFocus(); } - } + }; onSuggestionClick: React.MouseEventHandler = (e) => { const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index') as any); e.preventDefault(); this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); this.textarea?.focus(); - } + }; shouldComponentUpdate(nextProps: IAutosuggesteTextarea, nextState: any) { // Skip updating when only the lastToken changes so the @@ -169,14 +169,14 @@ class AutosuggestTextarea extends ImmutablePureComponent setTextarea: React.Ref = (c) => { this.textarea = c; - } + }; onPaste: React.ClipboardEventHandler = (e) => { if (e.clipboardData && e.clipboardData.files.length === 1) { this.props.onPaste(e.clipboardData.files); e.preventDefault(); } - } + }; renderSuggestion = (suggestion: string | Emoji, i: number) => { const { selectedSuggestion } = this.state; @@ -208,7 +208,7 @@ class AutosuggestTextarea extends ImmutablePureComponent {inner} ); - } + }; setPortalPosition() { if (!this.textarea) { diff --git a/app/soapbox/components/dropdown-menu.tsx b/app/soapbox/components/dropdown-menu.tsx index 202c43fa8f..3cab63aeb5 100644 --- a/app/soapbox/components/dropdown-menu.tsx +++ b/app/soapbox/components/dropdown-menu.tsx @@ -64,7 +64,7 @@ class DropdownMenu extends React.PureComponent = c => { this.node = c; - } + }; setFocusRef: React.RefCallback = c => { this.focusedItem = c; - } + }; handleKeyDown = (e: KeyboardEvent) => { if (!this.node) return; @@ -127,13 +127,13 @@ class DropdownMenu extends React.PureComponent = e => { if (e.key === 'Enter' || e.key === ' ') { this.handleClick(e); } - } + }; handleClick: React.EventHandler = e => { const i = Number(e.currentTarget.getAttribute('data-index')); @@ -152,7 +152,7 @@ class DropdownMenu extends React.PureComponent = e => { const i = Number(e.currentTarget.getAttribute('data-index')); @@ -166,13 +166,13 @@ class DropdownMenu extends React.PureComponent = e => { if (e.button === 1) { this.handleMiddleClick(e); } - } + }; renderItem(option: MenuItem | null, i: number): JSX.Element { if (option === null) { @@ -303,7 +303,7 @@ class Dropdown extends React.PureComponent { onOpen(this.state.id, this.handleItemClick, placement, e.type !== 'click'); } - } + }; handleClose = () => { if (this.activeElement && this.activeElement === this.target) { @@ -314,13 +314,13 @@ class Dropdown extends React.PureComponent { if (this.props.onClose) { this.props.onClose(this.state.id); } - } + }; handleMouseDown: React.EventHandler = () => { if (!this.state.open) { this.activeElement = document.activeElement; } - } + }; handleButtonKeyDown: React.EventHandler = (e) => { switch (e.key) { @@ -329,7 +329,7 @@ class Dropdown extends React.PureComponent { this.handleMouseDown(e); break; } - } + }; handleKeyPress: React.EventHandler> = (e) => { switch (e.key) { @@ -340,7 +340,7 @@ class Dropdown extends React.PureComponent { e.preventDefault(); break; } - } + }; handleItemClick: React.EventHandler = e => { const i = Number(e.currentTarget.getAttribute('data-index')); @@ -358,21 +358,21 @@ class Dropdown extends React.PureComponent { } else if (to) { this.props.history?.push(to); } - } + }; setTargetRef: React.RefCallback = c => { this.target = c; - } + }; findTarget = () => { return this.target; - } + }; componentWillUnmount = () => { if (this.state.id === this.props.openDropdownId) { this.handleClose(); } - } + }; render() { const { src = require('@tabler/icons/dots.svg'), items, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard = false, pressed, text, children, dropdownMenuStyle } = this.props; diff --git a/app/soapbox/components/emoji-selector.tsx b/app/soapbox/components/emoji-selector.tsx index 43e10d8756..be0ca3a51c 100644 --- a/app/soapbox/components/emoji-selector.tsx +++ b/app/soapbox/components/emoji-selector.tsx @@ -28,7 +28,7 @@ class EmojiSelector extends ImmutablePureComponent { onReact: () => { }, onUnfocus: () => { }, visible: false, - } + }; node?: HTMLDivElement = undefined; @@ -38,7 +38,7 @@ class EmojiSelector extends ImmutablePureComponent { if (focused && (!e.currentTarget || !e.currentTarget.classList.contains('emoji-react-selector__emoji'))) { onUnfocus(); } - } + }; _selectPreviousEmoji = (i: number): void => { if (!this.node) return; @@ -85,7 +85,7 @@ class EmojiSelector extends ImmutablePureComponent { onUnfocus(); break; } - } + }; handleReact = (emoji: string) => (): void => { const { onReact, focused, onUnfocus } = this.props; @@ -95,7 +95,7 @@ class EmojiSelector extends ImmutablePureComponent { if (focused) { onUnfocus(); } - } + }; handlers = { open: () => { }, @@ -103,7 +103,7 @@ class EmojiSelector extends ImmutablePureComponent { setRef = (c: HTMLDivElement): void => { this.node = c; - } + }; render() { const { visible, focused, allowedEmoji, onReact } = this.props; diff --git a/app/soapbox/components/error-boundary.tsx b/app/soapbox/components/error-boundary.tsx index 370472cb45..0440de85bb 100644 --- a/app/soapbox/components/error-boundary.tsx +++ b/app/soapbox/components/error-boundary.tsx @@ -42,7 +42,7 @@ class ErrorBoundary extends React.PureComponent { error: undefined, componentStack: undefined, browser: undefined, - } + }; textarea: HTMLTextAreaElement | null = null; @@ -71,7 +71,7 @@ class ErrorBoundary extends React.PureComponent { setTextareaRef: React.RefCallback = c => { this.textarea = c; - } + }; handleCopy: React.MouseEventHandler = () => { if (!this.textarea) return; @@ -80,12 +80,12 @@ class ErrorBoundary extends React.PureComponent { this.textarea.setSelectionRange(0, 99999); document.execCommand('copy'); - } + }; getErrorText = (): string => { const { error, componentStack } = this.state; return error + componentStack; - } + }; clearCookies: React.MouseEventHandler = (e) => { localStorage.clear(); @@ -96,7 +96,7 @@ class ErrorBoundary extends React.PureComponent { e.preventDefault(); unregisterSw().then(goHome).catch(goHome); } - } + }; render() { const { browser, hasError } = this.state; diff --git a/app/soapbox/components/ui/form-group/__tests__/form-group.test.tsx b/app/soapbox/components/ui/form-group/__tests__/form-group.test.tsx index 676631a3b5..a762000922 100644 --- a/app/soapbox/components/ui/form-group/__tests__/form-group.test.tsx +++ b/app/soapbox/components/ui/form-group/__tests__/form-group.test.tsx @@ -3,8 +3,6 @@ import React from 'react'; import { render, screen } from '../../../../jest/test-helpers'; import FormGroup from '../form-group'; -jest.mock('uuid', () => jest.requireActual('uuid')); - describe('', () => { it('connects the label and input', () => { render( diff --git a/app/soapbox/features/audio/visualizer.ts b/app/soapbox/features/audio/visualizer.ts index 4108790285..541b6210b5 100644 --- a/app/soapbox/features/audio/visualizer.ts +++ b/app/soapbox/features/audio/visualizer.ts @@ -15,10 +15,10 @@ const hex2rgba = (hex: string, alpha = 1) => { export default class Visualizer { - tickSize: number - canvas?: HTMLCanvasElement - context?: CanvasRenderingContext2D - analyser?: AnalyserNode + tickSize: number; + canvas?: HTMLCanvasElement; + context?: CanvasRenderingContext2D; + analyser?: AnalyserNode; constructor(tickSize: number) { this.tickSize = tickSize; diff --git a/app/soapbox/features/feed-filtering/feed-carousel.tsx b/app/soapbox/features/feed-filtering/feed-carousel.tsx index 19e1c34008..c16d3bd78e 100644 --- a/app/soapbox/features/feed-filtering/feed-carousel.tsx +++ b/app/soapbox/features/feed-filtering/feed-carousel.tsx @@ -159,7 +159,7 @@ const FeedCarousel = () => {