---
title: Stil Veileder
image: /images/user-guide/notes/notes_header.png
---

<Frame>
  <img src="/images/user-guide/notes/notes_header.png" alt="Header" />
</Frame>

Dette dokumentet inkluderer reglene som skal følges når man skriver kode.

Målet her er å ha en konsekvent kodebase som er enkel å lese og vedlikeholde.

For dette er det bedre å være litt mer omstendelig enn å være for konsis.

Husk alltid at folk leser kode oftere enn de skriver den, spesielt i et åpen kildekodeprosjekt, hvor hvem som helst kan bidra.

Det er mange regler som ikke er definert her, men som sjekkes automatisk av lintverktøy.

## React

### Bruk funksjonelle komponenter

Bruk alltid TSX funksjonelle komponenter.

Ikke bruk standard `import` med `const`, fordi det er vanskeligere å lese og vanskeligere å importere med kodefullføring.

```tsx
// ❌ Bad, harder to read, harder to import with code completion
const MyComponent = () => {
  return <div>Hello World</div>;
};

export default MyComponent;

// ✅ Good, easy to read, easy to import with code completion
export function MyComponent() {
  return <div>Hello World</div>;
};
```

### Props

Create the type of the props and call it `(ComponentName)Props` if there's no need to export it.

Bruk destructuring av props.

```tsx
// ❌ Bad, no type
export const MyComponent = (props) => <div>Hello {props.name}</div>;

// ✅ Good, type
type MyComponentProps = {
  name: string;
};

export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
```

#### Unngå å bruke `React.FC` eller `React.FunctionComponent` for å definere proptype

```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 }) => <TextInput value={value} disabled fullWidth />;
```

```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) => (
  <TextInput value={value} disabled fullWidth />
);
```

#### Ingen Enkel Variabel Prop Spredning i JSX Elementer

Unngå å bruke enkel variabel prop spredning i JSX elementer, som `{...props}`. Denne praksisen resulterer ofte i kode som er mindre leselig og vanskeligere å vedlikeholde fordi det er uklart hvilke props komponenten mottar.

```tsx
/* ❌ - Bad, spreads a single variable prop into the underlying component
 */
const MyComponent = (props: OwnProps) => {
  return <OtherComponent {...props} />;
}
```

```tsx
/* ✅ - Good, Explicitly lists all props
 *    - Enhances readability and maintainability
 */ 
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
  return <OtherComponent {...{ prop1, prop2, prop3 }} />;
};
```

Begrunnelse:

- Ved et øyekast er det tydeligere hvilke props koden videresender, noe som gjør det lettere å forstå og vedlikeholde.
- Det hjelper å forhindre tett kobling mellom komponenter via deres props.
- Lintverktøy gjør det lettere å identifisere feilstavede eller ubrukte props når du lister opp props eksplisitt.

## JavaScript

### Bruk nullish-coalescing 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';
```

### Bruk valgfri chaining `?.`

```tsx
// ❌ Bad 
onClick && onClick();

// ✅ Good
onClick?.();
```

## TypeScript

### Bruk `type` i stedet for `interface`

Bruk alltid `type` i stedet for `interface`, fordi de nesten alltid overlapper, og `type` er mer fleksibelt.

```tsx
// ❌ Bad
interface MyInterface {
  name: string;
}

// ✅ Good
type MyType = {
  name: string;
};
```

### Bruk strengbokstaver i stedet for enums

[Strengbokstaver](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) er måten å håndtere enum-lignende verdier i TypeScript. De er lettere å utvide med Pick og Omit, og gir en bedre utvikleropplevelse, særlig med kodefullføring.

Du kan se hvorfor TypeScript anbefaler å unngå enums [her](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 og interne biblioteker

Du bør bruke enums som GraphQL codegen genererer.

Det er også bedre å bruke en enum når man bruker et internt bibliotek, slik at det interne biblioteket ikke må eksponere en strengbokstavtype som ikke er relatert til den interne API-en.

Eksempel:

```TSX
const {
  setHotkeyScopeAndMemorizePreviousScope,
  goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();

setHotkeyScopeAndMemorizePreviousScope(
  RelationPickerHotkeyScope.RelationPicker,
);
```

## Stilsetting

### Bruk StyledComponents

Style komponentene med [styled-components](https://emotion.sh/docs/styled).

```tsx
// ❌ Bad
<div className="my-class">Hello World</div>
```

```tsx
// ✅ Good
const StyledTitle = styled.div`
  color: red;
`;
```

Forankre styled komponentene med "Styled" for å skille dem fra "virkelige" komponenter.

```tsx
// ❌ Bad
const Title = styled.div`
  color: red;
`;
```

```tsx
// ✅ Good
const StyledTitle = styled.div`
  color: red;
`;
```

### Tematisering

Å bruke temaet til hoveddelen av komponentstilingen er den foretrukne tilnærmingen.

#### Måleenheter

Unngå å bruke `px` eller `rem` verdier direkte i styled komponenter. De nødvendige verdiene er vanligvis allerede definert i temaet, så det anbefales å benytte temaet for disse formålene.

#### Farger

Unngå å introdusere nye farger, bruk heller den eksisterende paletten fra temaet. Skulle det være en situasjon der paletten ikke stemmer, vennligst legg igjen en kommentar slik at teamet kan rette det opp.

```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};
`;
```

## Håndheve Ingen-Type Importer

Unngå type importeringer. For å håndheve denne standarden sjekker en ESLint-regel type importeringer og rapporterer eventuelle brudd. Dette hjelper med å opprettholde konsistens og lesbarhet 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';
```

### Hvorfor Ingen-Type Importer

- **Konsistens**: Ved å unngå type importeringer og bruke en enkelt tilnærming for både type- og verdimporteringer holder kodebasen seg konsekvent i sin modulimportstil.

- **Lesbarhet**: Ingen-type importeringer forbedrer kodelesbarhet ved å gjøre det tydelig når du importerer verdier eller typer. Dette reduserer tvetydighet og gjør det lettere å forstå hensikten med importerte 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. This rule will generate errors or warnings for any type import violations.

Please note that this rule specifically addresses rare edge cases where unintentional type imports occur. TypeScript selv fraråder denne praksisen, som nevnt i [TypeScript 3.8 utgivelsesnotater](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports.

For å sikre at koden din overholder denne regelen, må du sørge for å kjøre ESLint som en del av utviklingsarbeidsflyten din.
