Skip to content

Instantly share code, notes, and snippets.

@isBatak
Last active May 8, 2021 13:33
Show Gist options
  • Save isBatak/c71f15d94919c037ebffcc8eeac5417d to your computer and use it in GitHub Desktop.
Save isBatak/c71f15d94919c037ebffcc8eeac5417d to your computer and use it in GitHub Desktop.
project structure

UI Components

When adding UI components, you should be able to group them in two root domains:

  1. pages - page scope based components
  2. shared - components that are shared all across the app

Folder naming rules:

  1. kebab-case folder name indicates domain name
  2. PascalCase folders and filenames should be used for components naming
src
├── components
│   ├── pages
│   │   ├── home
│   │   │   ├── HomeHeaderSection
│   │   │   │   └── HomeHeaderSection.tsx
│   │   │   └── HomeTodoListSection
│   │   │       └── HomeTodoListSection.tsx
│   │   └── todo
│   │       ├── TodoHeaderSection
│   │       │   └── TodoHeaderSection.tsx
│   │       └── TodoCreateFormSection
│   │           └── TodoCreateFormSection.tsx
│   └── shared
│       ├── core
│       │   ├── Section
│       │   │   └── Section.tsx
│       │   └── Card
│       │       └── Card.tsx
│       ├── fields
│       │   └── TextField
│       │       └── TextField.tsx
│       └── todo
│           ├── TodoCard
│           │   └── TodoCard.tsx
│           ├── TodoList
│           │   └── TodoList.tsx
│           └── TodoCreateForm
│               └── TodoCreateForm.tsx
└── pages
    ├── index.tsx
    └── todo
        └── [id]
            └── index.tsx

Shared core components

We can refer to them as atoms, smallest building blocks, highly reusable and composable. You can check the Open UI standard proposal for inspiration how to split components into small segments. Components could be designed as Compound Components or Black-box Components with good "inversion of control" interface like ReactSelect.

Components Parts Description
Card
`Card`, `CardImage`, `CardImageOverlay`, `CardTitle`, `CardDescription`, ...
From these parts, you'll be able to compose multiple more specific **_molecules_** like `ProductCard` or `UserCard`.
Section `Section`, `SectionHeader`, `SectionBody`, .. This might have multiple background schemes like `dimmed`, `inverted`, `light`.
Search `Search`, `SearchInput`, `SearchEmpty`, SearchResults`, ... `Search` uses context to provide shared state to other parts. `SearchInput` renders input and it could be placed anywhere in the DOM structure (for example, in the page `Header`). `SearchEmpty` and `SearchResults` handles switching between states and showing the result.
ReactSelect `ReactSelect`, `./components/ClearIndicator`, `./components/Control`, ... The list of custom components can be find [here](https://react-select.com/components)

Shared Feature based domains

We can refer to them as molecules. They are more specific components built out of atoms (core components). They are shared components that encapsulate some specific feature of an app.

Component name is always composed out of two parts Context + Domain, for example ArticlesPanel where Articles is context and Panel is domain.

Here are some examples of feature domain names:

Domains Components Description
`fields` `InputField`, `TextareaField` Specific form fields prepared to be used with [React Hook Form](https://react-hook-form.com/) library. Built out of multiple parts, for example `InputGroup`, `InputLeftElement`, `Input` form [Chakra UI](https://chakra-ui.com/docs/form/input#add-elements-inside-input)
`overlays` `UnsupportedBrowserOverlay`, `BugsnagErrorOverlay` Components that covers the whole page and prevents user to interact with the page in some degree.
`layouts` `MainLayout`, `AdminLayout` Components that are shared across the pages and renders the application shell (navigation and footer)
`messages` `NoResultsMessage`, `EmptyListMessage`, `LoadingMessage`, `ErrorMessage` Reusable messages components that could be shared across the pages for handling empty list results, loading states or ErrorBoundaries fallback
`navigations` `MainNavigation`, `AdminNavigation` Different navigations used in layouts to support different app shell styles. They could handle user logged-in/logged-out states and mobile/desktop layouts
`footers` `MainFooter`, `AdminFooter` Different footers used in layouts to support different app shell styles. Serves the same purpose as `navigations`
`panels` `ArticlesPanel`, `EventPanel`, `EventSidebarPanel`, `GroupPanel` Specific panels that holds filtering dropdowns for narrowing down the list results. Usually consists of core `Panel` compound component for sharing the styles and sorting dropdowns.
`markdowns` `ArticleMarkdown`, `AnnouncementMarkdown` Components that handles parsing of the markdown and styling of the generated HTML

Shared Entity based domain

We can refer to them as molecules also, but they are tied to some entity, for example Datx model, algolia resource, google map entity.

Component name is always composed out of two parts Entity + Context, for example TodoList where Todo is entity and List is context.

Domains Components Description
`todo` `TodoList`, `TodoCreateForm`, `TodoCard`, ... They should accept primitive props like `resourceId` and hook to the resource fetching layer via `SWR`.
`user` `UserList`, `UserCreateForm`, `UserCard`, ...
`ticket` `TicketList`, `TicketCreateForm`, `TicketCard`, ...

Shared utility domain

Utility components usually does not have any visual representation on the screen, but they are still reusable declarative components.

Domains Components Description
`utilities` `Meta`, `BugsnagErrorBoundary` `Meta` inserts `meta` tags into document `head`. `BugsnagErrorBoundary` catches the error, triggers the Bugsnag report and render fallback component
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment