diff --git a/.eslintrc.json b/.eslintrc.json index c8c1a9d0..6e652b2c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,33 +7,38 @@ "plugin:react-hooks/recommended", "plugin:jsx-a11y/recommended" ], - "plugins": [ - "@typescript-eslint", - "react", - "jsx-a11y" - ], + "plugins": ["@typescript-eslint", "react", "jsx-a11y"], "rules": { "react/react-in-jsx-scope": "off", "react/prop-types": "off", "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], + "@typescript-eslint/no-unused-vars": [ + "error", + { "argsIgnorePattern": "^_" } + ], "@typescript-eslint/no-explicit-any": "error", "no-console": ["warn", { "allow": ["warn", "error"] }], "prefer-const": "error", - "jsx-a11y/anchor-is-valid": ["error", { - "components": ["Link"], - "specialLink": ["hrefLeft", "hrefRight"], - "aspects": ["invalidHref", "preferButton"] - }], + "jsx-a11y/anchor-is-valid": [ + "error", + { + "components": ["Link"], + "specialLink": ["hrefLeft", "hrefRight"], + "aspects": ["invalidHref", "preferButton"] + } + ], "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", - "jsx-a11y/label-has-associated-control": ["error", { - "labelComponents": [], - "labelAttributes": [], - "controlComponents": [], - "assert": "either", - "depth": 25 - }] + "jsx-a11y/label-has-associated-control": [ + "error", + { + "labelComponents": [], + "labelAttributes": [], + "controlComponents": [], + "assert": "either", + "depth": 25 + } + ] }, "settings": { "react": { diff --git a/__tests__/UI/Tabs.test.tsx b/__tests__/UI/Tabs.test.tsx index fe6a320a..c4f26e56 100644 --- a/__tests__/UI/Tabs.test.tsx +++ b/__tests__/UI/Tabs.test.tsx @@ -68,7 +68,7 @@ describe("Tabs", () => { const tabElement = screen.getByRole("tab", { name: tab.label }); expect(tabElement).toHaveAttribute( "aria-selected", - index === 0 ? "true" : "false" + index === 0 ? "true" : "false", ); expect(tabElement).toHaveAttribute("aria-controls", `tabpanel-${tab.id}`); }); diff --git a/src/components/ErrorBoundary/ErrorBoundary.tsx b/src/components/ErrorBoundary/ErrorBoundary.tsx index 9c7a6ad3..55e58b84 100644 --- a/src/components/ErrorBoundary/ErrorBoundary.tsx +++ b/src/components/ErrorBoundary/ErrorBoundary.tsx @@ -1,7 +1,10 @@ "use client"; import React, { ReactNode, ErrorInfo } from "react"; -import { ErrorBoundary as ReactErrorBoundary, FallbackProps } from "react-error-boundary"; +import { + ErrorBoundary as ReactErrorBoundary, + FallbackProps, +} from "react-error-boundary"; import Fallback from "./Fallback.component"; interface ErrorBoundaryProps { @@ -18,7 +21,10 @@ interface ErrorBoundaryProps { * @param {boolean} props.compact - Whether to show a compact error fallback (used in stories) * @returns {JSX.Element} A React component that catches errors in its child components */ -const ErrorBoundary: React.FC = ({ children, compact = false }) => { +const ErrorBoundary: React.FC = ({ + children, + compact = false, +}) => { const handleError = (error: Error, info: ErrorInfo) => { console.error("Uventet feil i Matrix:", error, info); }; @@ -28,10 +34,7 @@ const ErrorBoundary: React.FC = ({ children, compact = false }; return ( - + {children} ); diff --git a/src/components/ErrorBoundary/ErrorFallback.component.tsx b/src/components/ErrorBoundary/ErrorFallback.component.tsx index 853e4dec..b892f6fb 100644 --- a/src/components/ErrorBoundary/ErrorFallback.component.tsx +++ b/src/components/ErrorBoundary/ErrorFallback.component.tsx @@ -16,7 +16,10 @@ interface ErrorFallbackProps { * @param {boolean} props.compact - Whether to show a compact version (used in stories) * @returns {JSX.Element} A React component displaying the error message and reload option */ -const ErrorFallback: React.FC = ({ error, compact = false }) => { +const ErrorFallback: React.FC = ({ + error, + compact = false, +}) => { if (compact) { return (
diff --git a/src/components/ErrorBoundary/ErrorFallbackWrapper.component.tsx b/src/components/ErrorBoundary/ErrorFallbackWrapper.component.tsx index d23689e0..d8dc1e28 100644 --- a/src/components/ErrorBoundary/ErrorFallbackWrapper.component.tsx +++ b/src/components/ErrorBoundary/ErrorFallbackWrapper.component.tsx @@ -13,8 +13,9 @@ interface ErrorFallbackWrapperProps { * @param {boolean} props.compact - Whether to show a compact version * @returns {JSX.Element} The wrapped ErrorFallback component */ -const ErrorFallbackWrapper: React.FC = ({ error, compact }) => ( - -); +const ErrorFallbackWrapper: React.FC = ({ + error, + compact, +}) => ; export default ErrorFallbackWrapper; diff --git a/src/components/Layout/MobileMenu.component.tsx b/src/components/Layout/MobileMenu.component.tsx index 282c7bc6..a273ff56 100644 --- a/src/components/Layout/MobileMenu.component.tsx +++ b/src/components/Layout/MobileMenu.component.tsx @@ -117,55 +117,53 @@ const MobileMenu = ({ links }: IMobileMenuProps) => { }, }} > - {links.map( - ({ title, name, href, externalLink }, index) => ( - - {externalLink ? ( - + {links.map(({ title, name, href, externalLink }, index) => ( + + {externalLink ? ( + + {name} + + ) : ( + +
{name} - - ) : ( - -
- {name} - -
- - )} - - ), - )} + +
+ + )} +
+ ))} diff --git a/src/stories/components/Footer.stories.tsx b/src/stories/components/Footer.stories.tsx index 79f1f8f1..c2c86b40 100644 --- a/src/stories/components/Footer.stories.tsx +++ b/src/stories/components/Footer.stories.tsx @@ -23,7 +23,7 @@ export const WithContent = () => ( // Narrow viewport export const NarrowViewport = () => ( -
+
); diff --git a/src/stories/components/GenericForm.stories.tsx b/src/stories/components/GenericForm.stories.tsx index 532a7d16..8681e0b9 100644 --- a/src/stories/components/GenericForm.stories.tsx +++ b/src/stories/components/GenericForm.stories.tsx @@ -26,10 +26,11 @@ const feedbackSchema = z.object({ feedback: z.string().min(20, "Feedback must be at least 20 characters"), }); -type FormData = z.infer | - z.infer | - z.infer | - { email: string }; +type FormData = + | z.infer + | z.infer + | z.infer + | { email: string }; // Example async submit handlers const mockSubmit = async (data: FormData) => { diff --git a/src/stories/components/Hamburger.stories.tsx b/src/stories/components/Hamburger.stories.tsx index b4e6b916..ba1cb435 100644 --- a/src/stories/components/Hamburger.stories.tsx +++ b/src/stories/components/Hamburger.stories.tsx @@ -24,13 +24,10 @@ export const XState = () => ( // Interactive state export const Interactive = () => { const [isOpen, setIsOpen] = useState(false); - + return (
- setIsOpen(!isOpen)} - animatetoX={isOpen} - /> + setIsOpen(!isOpen)} animatetoX={isOpen} />

Click the hamburger to toggle state

@@ -41,13 +38,10 @@ export const Interactive = () => { // On dark background export const OnDarkBackground = () => { const [isOpen, setIsOpen] = useState(false); - + return (
- setIsOpen(!isOpen)} - animatetoX={isOpen} - /> + setIsOpen(!isOpen)} animatetoX={isOpen} />
); }; @@ -55,14 +49,11 @@ export const OnDarkBackground = () => { // On light background export const OnLightBackground = () => { const [isOpen, setIsOpen] = useState(false); - + return (
- setIsOpen(!isOpen)} - animatetoX={isOpen} - /> + setIsOpen(!isOpen)} animatetoX={isOpen} />
); diff --git a/src/stories/components/InputField.stories.tsx b/src/stories/components/InputField.stories.tsx index bf2f7b9a..221c596a 100644 --- a/src/stories/components/InputField.stories.tsx +++ b/src/stories/components/InputField.stories.tsx @@ -1,6 +1,8 @@ import React from "react"; import { Meta, Story } from "@ladle/react"; -import InputField, { InputProps } from "../../components/UI/InputField.component"; +import InputField, { + InputProps, +} from "../../components/UI/InputField.component"; import { useForm, FieldValues } from "react-hook-form"; export default { @@ -18,14 +20,16 @@ interface StoryFormValues extends FieldValues { } // Wrapper component to provide form context -const InputFieldWrapper = (props: Omit, "register">) => { +const InputFieldWrapper = ( + props: Omit, "register">, +) => { const { register } = useForm(); return ; }; -const Template: Story, "register">> = (args) => ( - -); +const Template: Story, "register">> = ( + args, +) => ; export const Default = Template.bind({}); Default.args = { diff --git a/src/stories/components/Matrix.stories.tsx b/src/stories/components/Matrix.stories.tsx index 625e3998..2664903a 100644 --- a/src/stories/components/Matrix.stories.tsx +++ b/src/stories/components/Matrix.stories.tsx @@ -16,7 +16,8 @@ export default { // Client-side only wrapper component const ClientOnlyMatrix = (props: ReactMatrixAnimationProps) => { - const [Matrix, setMatrix] = useState | null>(null); + const [Matrix, setMatrix] = + useState | null>(null); useEffect(() => { import("../../components/Animations/Matrix.component").then((mod) => { @@ -32,9 +33,7 @@ const ClientOnlyMatrix = (props: ReactMatrixAnimationProps) => { }; const Container = ({ children }: { children: React.ReactNode }) => ( -
- {children} -
+
{children}
); // Basic story with default props diff --git a/src/stories/components/NavigationLink.stories.tsx b/src/stories/components/NavigationLink.stories.tsx index 6eb5a89d..0780ed51 100644 --- a/src/stories/components/NavigationLink.stories.tsx +++ b/src/stories/components/NavigationLink.stories.tsx @@ -3,7 +3,15 @@ import { Meta } from "@ladle/react"; import "../../app/glitch.css"; // Mock NavigationLink component for stories -const NavigationLink = ({ name, href, isActive }: { name: string; href: string; isActive: boolean }) => ( +const NavigationLink = ({ + name, + href, + isActive, +}: { + name: string; + href: string; + isActive: boolean; +}) => ( @@ -36,43 +44,23 @@ export default { // Default state export const Default = () => (
- +
); // Active state export const Active = () => (
- +
); // Multiple links export const MultipleLinks = () => (
- - - + + +
); @@ -91,27 +79,15 @@ export const LongText = () => ( export const OnDifferentBackgrounds = () => (
- +
- +
- +
- +
- +
); @@ -120,21 +96,9 @@ export const OnDifferentBackgrounds = () => ( export const HorizontalLayout = () => (
); diff --git a/src/stories/components/SkipLink.stories.tsx b/src/stories/components/SkipLink.stories.tsx index e840c118..5870e7dc 100644 --- a/src/stories/components/SkipLink.stories.tsx +++ b/src/stories/components/SkipLink.stories.tsx @@ -22,7 +22,9 @@ export const WithContext = () => (

Main Content

This story demonstrates the SkipLink in context with a page layout.

-

Tab to focus on the SkipLink - it will appear at the top of the page.

+

+ Tab to focus on the SkipLink - it will appear at the top of the page. +

); @@ -34,8 +36,8 @@ export const Focused = () => (

- This story shows how the SkipLink appears when focused. - The skip link is permanently visible here for demonstration purposes. + This story shows how the SkipLink appears when focused. The skip link is + permanently visible here for demonstration purposes.

); diff --git a/src/stories/components/Tabs.stories.tsx b/src/stories/components/Tabs.stories.tsx index 06ea76a6..80f5fd7a 100644 --- a/src/stories/components/Tabs.stories.tsx +++ b/src/stories/components/Tabs.stories.tsx @@ -40,7 +40,10 @@ const FormContent = () => {

Form Content

-
-