---
title: Przewodnik Stylu
image: /images/user-guide/notes/notes_header.png
---

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

Ten dokument zawiera zasady, których należy przestrzegać podczas pisania kodu.

Celem jest utrzymanie spójnej bazy kodu, która jest łatwa do czytania i łatwa do utrzymania.

W tym przypadku lepiej być nieco bardziej rozwlekłym niż zbyt zwięzłym.

Pamiętaj, że kod jest częściej czytany niż pisany, zwłaszcza w projekcie open source, gdzie każdy może przyczynić się do jego rozwoju.

There are a lot of rules that are not defined here, but that are automatically checked by linters.

## React

### Używaj komponentów funkcyjnych

Zawsze używaj komponentów funkcyjnych TSX.

Nie używaj domyślnego `import` z `const`, ponieważ trudniej go czytać i utrudnia import z automatycznym uzupełnianiem kodu.

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

### Właściwości (Props)

Utwórz typ propsów i nazwij go `(ComponentName)Props`, jeśli nie ma potrzeby eksportowania ich.

Używaj destrukturyzacji propsów.

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

#### Powstrzymaj się od używania `React.FC` lub `React.FunctionComponent`, aby definiować typy propów

```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 />
);
```

#### Brak rozprowadzania pojedynczych zmiennych-propów w elementach JSX

Unikaj używania rozprowadzania pojedynczych zmiennych-propów w elementach JSX, takich jak `{...props}`. Ten sposób często prowadzi do kodu, który jest mniej czytelny i trudniejszy do utrzymania, ponieważ nie jest jasne, jakie propy przyjmuje komponent.

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

Uzasadnienie:

- Na pierwszy rzut oka jest widoczne, jakie propy są przekazywane przez kod, co ułatwia jego zrozumienie i konserwację.
- Pomaga to zapobiegać ścisłemu powiązaniu pomiędzy komponentami poprzez ich propy.
- Narzędzia do lintowania ułatwiają identyfikację błędnie napisanych lub nieużywanych propów, gdy wyraźnie wymienisz propy.

## JavaScript

### Używaj operatora współinicjalizującego `??`

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

### Używaj opcjonalnych łańcuchów `?.`

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

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

## TypeScript

### Używaj `type` zamiast `interface`

Zawsze używaj `type` zamiast `interface`, ponieważ prawie zawsze się pokrywają, a `type` jest bardziej elastyczny.

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

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

### Używaj literałów stringowych zamiast enumeracji

[Literały stringowe](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) są najlepszym sposobem na obsługę wartości podobnych do enumeracji w TypeScript. Są łatwiejsze do rozszerzenia przy użyciu Pick i Omit, oferując lepsze doświadczenie programistyczne, szczególnie przy automatycznym uzupełnianiu kodu.

Możesz zobaczyć, dlaczego TypeScript zaleca unikanie enumeracji [tutaj](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 i biblioteki wewnętrzne

Powinieneś używać enumeracji generowanych przez kodowanie GraphQL.

Lepiej jest również używać enumeracji podczas korzystania z biblioteki wewnętrznej, aby nie musiała ona udostępniać typu literału stringowego, który nie jest związany z wewnętrznym API.

Przykład:

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

setHotkeyScopeAndMemorizePreviousScope(
  RelationPickerHotkeyScope.RelationPicker,
);
```

## Stylizacja

### Używaj StyledComponents

Styluj komponenty za pomocą [styled-components](https://emotion.sh/docs/styled).

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

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

Dodaj "Styled" przed nazwę stylowanym komponentom, aby odróżnić je od rzeczywistych komponentów.

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

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

### Tematyka

Preferowane podejście to korzystanie z motywu przy stylizacji większości komponentów.

#### Jednostki miar

Unikaj używania bezpośrednich wartości `px` lub `rem` w stylowanych komponentach. Potrzebne wartości są zazwyczaj już zdefiniowane w motywie, więc zaleca się korzystanie z niego do tych celów.

#### Kolory

Powstrzymaj się od wprowadzania nowych kolorów; zamiast tego używaj istniejącej palety z motywu. Jeśli przypadkiem paleta nie pasuje, prosimy o zostawienie komentarza, aby zespół mógł to naprawić.

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

## Egzekwowanie importów bez typów

Unikaj importów typów. Aby egzekwować ten standard, reguła ESLint sprawdza i raportuje każde naruszenie importu typu. To pomaga zachować spójność i czytelność kodu TypeScript.

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

### Dlaczego brak importów typów

- **Spójność**: Unikanie importów typu i używanie jednolitych podejść do importu typów i wartości, pozwala na zachowanie spójności w stylach importów modułów wewnątrz bazy kodu.

- **Czytelność**: Importy bez typów poprawiają czytelność kodu, jasno określając, kiedy importujesz wartości lub typy. Zmniejsza to niejednoznaczność i ułatwia zrozumienie celu importowanych symboli.

- **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code.

### Reguła ESLint

Reguła ESLint, `@typescript-eslint/consistent-type-imports`, wymusza standard importów bez typów. Ta reguła generuje błędy lub ostrzeżenia dla każdego naruszenia importu typu.

Należy zauważyć, że ta reguła dotyczy rzadkich przypadków brzegowych, gdy występują niezamierzone importy typu. TypeScript sam odradza tę praktykę, co jest wspomniane w [uwagach do wydania TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). W większości sytuacji nie powinieneś potrzebować używać importów tylko-typowych.

To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.
