--- title: Przewodnik Stylu image: /images/user-guide/notes/notes_header.png --- Header 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
Hello World
; }; export default MyComponent; // ✅ Good, easy to read, easy to import with code completion export function MyComponent() { return
Hello World
; }; ``` ### 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) =>
Hello {props.name}
; // ✅ Good, type type MyComponentProps = { name: string; }; export const MyComponent = ({ name }: MyComponentProps) =>
Hello {name}
; ``` #### 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 }) => ; ``` ```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) => ( ); ``` #### 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 ; } ``` ```tsx /* ✅ - Good, Explicitly lists all props * - Enhances readability and maintainability */ const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => { return ; }; ``` 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
Hello World
``` ```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.