Spaces:
Paused
Paused
|
Download docs/developer_docs/guidelines/frontend/component-style-guidelines.md from Leon4gr45/powerbi: direct link, hf CLI and curl.
- Browser
- Download file 7.06 kB
-
https://huggingface.co/spaces/Leon4gr45/powerbi/resolve/main/docs/developer_docs/guidelines/frontend/component-style-guidelines.md
- Command line
-
hf download hf://spaces/Leon4gr45/powerbi/docs/developer_docs/guidelines/frontend/component-style-guidelines.md
-
curl -L -o component-style-guidelines.md https://huggingface.co/spaces/Leon4gr45/powerbi/resolve/main/docs/developer_docs/guidelines/frontend/component-style-guidelines.md
7.06 kB
| title: Component Style Guidelines and Best Practices | |
| sidebar_position: 2 | |
| <!-- | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, | |
| software distributed under the License is distributed on an | |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| KIND, either express or implied. See the License for the | |
| specific language governing permissions and limitations | |
| under the License. | |
| --> | |
| # Component Style Guidelines and Best Practices | |
| This documentation illustrates how we approach component development in Superset and provides examples to help you in writing new components or updating existing ones by following our community-approved standards. | |
| This guide is intended primarily for reusable components. Whenever possible, all new components should be designed with reusability in mind. | |
| ## General Guidelines | |
| - We use [Ant Design](https://ant.design/) as our component library. Do not build a new component if Ant Design provides one but rather instead extend or customize what the library provides | |
| - Always style your component using Emotion and always prefer the theme variables whenever applicable. See: [Emotion Styling Guidelines and Best Practices](./emotion-styling-guidelines.md) | |
| - All components should be made to be reusable whenever possible | |
| - All components should follow the structure and best practices as detailed below | |
| ### Directory and component structure | |
| ``` | |
| superset-frontend/src/components | |
| {ComponentName}/ | |
| index.tsx | |
| {ComponentName}.test.tsx | |
| {ComponentName}.stories.tsx | |
| ``` | |
| **Components root directory:** Components that are meant to be re-used across different parts of the application should go in the `superset-frontend/src/components` directory. Components that are meant to be specific for a single part of the application should be located in the nearest directory where the component is used, for example, `superset-frontend/src/Explore/components` | |
| **Exporting the component:** All components within the `superset-frontend/src/components` directory should be exported from `superset-frontend/src/components/index.ts` to facilitate their imports by other components | |
| **Component directory name:** Use `PascalCase` for the component directory name | |
| **Storybook:** Components should come with a storybook file whenever applicable, with the following naming convention `\{ComponentName\}.stories.tsx`. More details about Storybook below | |
| **Unit and end-to-end tests:** All components should come with unit tests using Jest and React Testing Library. The file name should follow this naming convention `\{ComponentName\}.test.tsx`. Read the [Testing Guidelines and Best Practices](../../testing/testing-guidelines.md) for more details | |
| **Reference naming:** Use `PascalCase` for React components and `camelCase` for component instances | |
| **BAD:** | |
| ```jsx | |
| import mainNav from './MainNav'; | |
| ``` | |
| **GOOD:** | |
| ```jsx | |
| import MainNav from './MainNav'; | |
| ``` | |
| **BAD:** | |
| ```jsx | |
| const NavItem = <MainNav />; | |
| ``` | |
| **GOOD:** | |
| ```jsx | |
| const navItem = <MainNav />; | |
| ``` | |
| **Component naming:** Use the file name as the component name | |
| **BAD:** | |
| ```jsx | |
| import MainNav from './MainNav/index'; | |
| ``` | |
| **GOOD:** | |
| ```jsx | |
| import MainNav from './MainNav'; | |
| ``` | |
| **Props naming:** Do not use DOM related props for different purposes | |
| **BAD:** | |
| ```jsx | |
| <MainNav style="big" /> | |
| ``` | |
| **GOOD:** | |
| ```jsx | |
| <MainNav variant="big" /> | |
| ``` | |
| **Importing dependencies:** Only import what you need | |
| **BAD:** | |
| ```jsx | |
| import * as React from 'react'; | |
| ``` | |
| **GOOD:** | |
| ```jsx | |
| import React, { useState } from 'react'; | |
| ``` | |
| **Default VS named exports:** As recommended by [TypeScript](https://www.typescriptlang.org/docs/handbook/modules.html), "If a module's primary purpose is to house one specific export, then you should consider exporting it as a default export. This makes both importing and actually using the import a little easier". If you're exporting multiple objects, use named exports instead. | |
| _As a default export_ | |
| ```jsx | |
| import MainNav from './MainNav'; | |
| ``` | |
| _As a named export_ | |
| ```jsx | |
| import { MainNav, SecondaryNav } from './Navbars'; | |
| ``` | |
| **ARIA roles:** Always make sure you are writing accessible components by using the official [ARIA roles](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques) | |
| ## Use TypeScript | |
| All components should be written in TypeScript and their extensions should be `.ts` or `.tsx` | |
| ### type vs interface | |
| Validate all props with the correct types. This replaces the need for a run-time validation as provided by the prop-types library. | |
| ```tsx | |
| type HeadingProps = { | |
| param: string; | |
| }; | |
| export default function Heading({ children }: HeadingProps) { | |
| return <h2>{children}</h2>; | |
| } | |
| ``` | |
| Use `type` for your component props and state. Use `interface` when you want to enable _declaration merging_. | |
| ### Define default values for non-required props | |
| In order to improve the readability of your code and reduce assumptions, always add default values for non required props, when applicable, for example: | |
| ```tsx | |
| const applyDiscount = (price: number, discount = 0.05) => | |
| price * (1 - discount); | |
| ``` | |
| ## Functional components and Hooks | |
| We prefer functional components and the usage of hooks over class components. | |
| ### useState | |
| Always explicitly declare the type unless the type can easily be assumed by the declaration. | |
| ```tsx | |
| const [customer, setCustomer] = useState<ICustomer | null>(null); | |
| ``` | |
| ### useReducer | |
| Always prefer `useReducer` over `useState` when your state has complex logics. | |
| ### useMemo and useCallback | |
| Always memoize when your components take functions or complex objects as props to avoid unnecessary rerenders. | |
| ### Custom hooks | |
| All custom hooks should be located in the directory `/src/hooks`. Before creating a new custom hook, make sure that is not available in the existing custom hooks. | |
| ## Storybook | |
| Each component should come with its dedicated storybook file. | |
| **One component per story:** Each storybook file should only contain one component unless substantially different variants are required | |
| **Component variants:** If the component behavior is substantially different when certain props are used, it is best to separate the story into different types. See the `superset-frontend/packages/superset-ui-core/src/components/Select/Select.stories.tsx` as an example. | |
| **Isolated state:** The storybook should show how the component works in an isolated state and with as few dependencies as possible | |
| **Use args:** It should be possible to test the component with every variant of the available props. We recommend using [args](https://storybook.js.org/docs/react/writing-stories/args) | |