--- title: Stilguide image: /images/user-guide/notes/notes_header.png --- Header Det här dokumentet innehåller reglerna att följa när du skriver kod. Målet här är att ha en konsekvent kodbas, vilket är lätt att läsa och lätt att underhålla. För detta är det bättre att vara lite mer detaljerad än att vara för kortfattad. Kom alltid ihåg att folk läser kod oftare än de skriver den, speciellt i ett projekt med öppen källkod, där vem som helst kan bidra. Det finns många regler som inte definieras här, men som automatiskt kontrolleras av linters. ## React ### Använd funktionella komponenter Använd alltid TSX-funktionella komponenter. Använd inte standard `import` med `const`, eftersom det är svårare att läsa och svårare att importera med kodkomplettering. ```tsx // ❌ Bad, harder to read, harder to import with code completion const MyComponent = () => { return
Hello World
; }; export default MyComponent; // ✅ Good, easy to read, easy to import with code completion export function MyComponent() { return
Hello World
; }; ``` ### Egenskaper Skapa typen av props och kalla det `(ComponentName)Props` om det inte finns något behov av att exportera det. Använd destrukturering av props. ```tsx // ❌ Bad, no type export const MyComponent = (props) =>
Hello {props.name}
; // ✅ Good, type type MyComponentProps = { name: string; }; export const MyComponent = ({ name }: MyComponentProps) =>
Hello {name}
; ``` #### Avstå från att använda `React.FC` eller `React.FunctionComponent` för att definiera prop typer ```tsx /* ❌ - Bad, defines the component type annotations with `FC` * - With `React.FC`, the component implicitly accepts a `children` prop * even if it's not defined in the prop type. This might not always be * desirable, especially if the component doesn't intend to render * children. */ const EmailField: React.FC<{ value: string; }> = ({ value }) => ; ``` ```tsx /* ✅ - Good, a separate type (OwnProps) is explicitly defined for the * component's props * - This method doesn't automatically include the children prop. If * you want to include it, you have to specify it in OwnProps. */ type EmailFieldProps = { value: string; }; const EmailField = ({ value }: EmailFieldProps) => ( ); ``` #### Ingen enkel variabel propspridning i JSX-element Undvik att använda enkel variabel propspridning i JSX-element, som `{...props}`. Denna praxis resulterar ofta i kod som är mindre läsbar och svårare att underhålla eftersom det är oklart vilka props komponenten tar emot. ```tsx /* ❌ - Bad, spreads a single variable prop into the underlying component */ const MyComponent = (props: OwnProps) => { return ; } ``` ```tsx /* ✅ - Good, Explicitly lists all props * - Enhances readability and maintainability */ const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => { return ; }; ``` Motivering: - Vid en snabb blick är det tydligare vilka props som koden skickar vidare, vilket gör det lättare att förstå och underhålla. - Det hjälper till att förhindra tätt koppling mellan komponenter via deras props. - Lintverktyg gör det lättare att identifiera felstavade eller oanvända props när du listar props explicit. ## JavaScript ### Använd nullish-koalescerande operator `??` ```tsx // ❌ Bad, can return 'default' even if value is 0 or '' const value = process.env.MY_VALUE || 'default'; // ✅ Good, will return 'default' only if value is null or undefined const value = process.env.MY_VALUE ?? 'default'; ``` ### Använd valfri kedjeoperator `?.` ```tsx // ❌ Bad onClick && onClick(); // ✅ Good onClick?.(); ``` ## TypeScript ### Använd `type` istället för `interface` Använd alltid `type` istället för `interface`, eftersom de nästan alltid överlappar, och `type` är mer flexibel. ```tsx // ❌ Bad interface MyInterface { name: string; } // ✅ Good type MyType = { name: string; }; ``` ### Använd stränglitteraler istället för enums [Stränglitteraler](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) är det främsta sättet att hantera enum-liknande värden i TypeScript. De är enklare att utöka med Pick och Omit och ger en bättre utvecklarupplevelse, speciellt med kodkomplettering. Du kan se varför TypeScript rekommenderar att undvika enums [här](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums). ```tsx // ❌ Bad, utilizes an enum enum Color { Red = "red", Green = "green", Blue = "blue", } let color = Color.Red; ``` ```tsx // ✅ Good, utilizes a string literal let color: "red" | "green" | "blue" = "red"; ``` #### GraphQL och interna bibliotek Du bör använda enums som GraphQL codegen genererar. Det är också bättre att använda en enum när du använder ett internt bibliotek, så det interna biblioteket slipper exponera en stränglitteraltyp som inte är relaterad till den interna API:n. Exempel: ```TSX const { setHotkeyScopeAndMemorizePreviousScope, goBackToPreviousHotkeyScope, } = usePreviousHotkeyScope(); setHotkeyScopeAndMemorizePreviousScope( RelationPickerHotkeyScope.RelationPicker, ); ``` ## Stil ### Använd StyledComponents Styla komponenterna med [styled-components](https://emotion.sh/docs/styled). ```tsx // ❌ Bad
Hello World
``` ```tsx // ✅ Good const StyledTitle = styled.div` color: red; `; ``` Förställda komponenter med "Styled" för att särskilja dem från "riktiga" komponenter. ```tsx // ❌ Bad const Title = styled.div` color: red; `; ``` ```tsx // ✅ Good const StyledTitle = styled.div` color: red; `; ``` ### Teman Att använda temat för merparten av komponentens styling är den föredragna metoden. #### Måttenheter Undvik att använda `px` eller `rem` värden direkt inom de stilade komponenterna. De nödvändiga värdena är vanligtvis redan definierade i temat, så det rekommenderas att använda temat för dessa ändamål. #### Färger Avstå från att införa nya färger; använd istället den befintliga paletten från temat. Om det uppstår en situation där paletten inte stämmer överens, vänligen lämna en kommentar så att teamet kan åtgärda det. ```tsx // ❌ Bad, directly specifies style values without utilizing the theme const StyledButton = styled.button` color: #333333; font-size: 1rem; font-weight: 400; margin-left: 4px; border-radius: 50px; `; ``` ```tsx // ✅ Good, utilizes the theme const StyledButton = styled.button` color: ${({ theme }) => theme.font.color.primary}; font-size: ${({ theme }) => theme.font.size.md}; font-weight: ${({ theme }) => theme.font.weight.regular}; margin-left: ${({ theme }) => theme.spacing(1)}; border-radius: ${({ theme }) => theme.border.rounded}; `; ``` ## Tvingande icke-typ importerar Undvik typ-importer. För att upprätthålla denna standard kontrollerar en ESLint-regel och rapporterar eventuella typ-importeringar. Detta hjälper till att behålla konsekvens och läsbarhet i TypeScript koden. ```tsx // ❌ Bad import { type Meta, type StoryObj } from '@storybook/react'; // ❌ Bad import type { Meta, StoryObj } from '@storybook/react'; // ✅ Good import { Meta, StoryObj } from '@storybook/react'; ``` ### Varför inga typ-importer - **Konsekvens**: Genom att undvika typ-importer och använda en enskild metod för både typ och värde-importer förblir kodbasen konsekvent i sin modul-import stil. - **Läsbarhet**: Icke-typ importer förbättrar kodens läsbarhet genom att klargöra när du importerar värden eller typer. Detta minskar tvetydighet och gör det enklare att förstå syftet med importerade symboler. - **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code. ### ESLint-regel An ESLint rule, `@typescript-eslint/consistent-type-imports`, enforces the no-type import standard. Denna regel kommer att generera fel eller varningar för eventuella typ-import överträdelser. Observera att denna regel specifikt adresserar sällsynta hörnfall där oavsiktliga typ-importer sker. TypeScript själv avråder denna praxis, som nämns i [TypeScript 3.8 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports. To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.