Migrate to a monorepo structure (#2909)

This commit is contained in:
Charles Bochet
2023-12-10 18:10:54 +01:00
committed by GitHub
parent a70a9281eb
commit 5bdca9de6c
2304 changed files with 37152 additions and 25869 deletions

View File

@ -0,0 +1,3 @@
{
"position": 3
}

View File

@ -0,0 +1,4 @@
{
"label": "Advanced",
"position": 3
}

View File

@ -0,0 +1,330 @@
---
title: Best Practices
sidebar_position: 3
sidebar_custom_props:
icon: TbChecklist
---
This document outlines the best practices you should follow when working on the frontend.
## State management
React and Recoil handle state management in the codebase.
### Use `useRecoilState` to store state
It's good practice to create as many atoms as you need to store your state.
:::tip
It's better to use extra atoms than trying to be too concise with props drilling.
:::
```tsx
export const myAtomState = atom({
key: 'myAtomState',
default: 'default value',
});
export const MyComponent = () => {
const [myAtom, setMyAtom] = useRecoilState(myAtomState);
return (
<div>
<input
value={myAtom}
onChange={(e) => setMyAtom(e.target.value)}
/>
</div>
);
}
```
### Do not use `useRef` to store state
Avoid using `useRef` to store state.
If you want to store state, you should use `useState` or `useRecoilState`.
See [how to manage re-renders](#managing-re-renders) if you feel like you need `useRef` to prevent some re-renders from happening.
## Managing re-renders
Re-renders can be hard to manage in React.
Here are some rules to follow to avoid unnecessary re-renders.
Keep in mind that you can **always** avoid re-renders by understanding their cause.
### Work at the root level
Avoiding re-renders in new features is now made easy by eliminating them at the root level.
The `PageChangeEffect` sidecar component contains just one `useEffect` that holds all the logic to execute on a page change.
That way you know that there's just one place that can trigger a re-render.
### Always think twice before adding `useEffect` in your codebase
Re-renders are often caused by unnecessary `useEffect`.
You should think whether you need `useEffect`, or if you can move the logic in a event handler function.
You'll find it generally easy to move the logic in a `handleClick` or `handleChange` function.
You can also find them in libraries like Apollo: `onCompleted`, `onError`, etc.
### Use a sibling component to extract `useEffect` or data fetching logic
If you feel like you need to add a `useEffect` in your root component, you should consider extracting it in a sidecar component.
You can apply the same for data fetching logic, with Apollo hooks.
```tsx
// ❌ Bad, will cause re-renders even if data is not changing,
// because useEffect needs to be re-evaluated
export const PageComponent = () => {
const [data, setData] = useRecoilState(dataState);
const [someDependency] = useRecoilState(someDependencyState);
useEffect(() => {
if(someDependency !== data) {
setData(someDependency);
}
}, [someDependency]);
return <div>{data}</div>;
};
export const App = () => (
<RecoilRoot>
<PageComponent />
</RecoilRoot>
);
```
```tsx
// ✅ Good, will not cause re-renders if data is not changing,
// because useEffect is re-evaluated in another sibling component
export const PageComponent = () => {
const [data, setData] = useRecoilState(dataState);
return <div>{data}</div>;
};
export const PageData = () => {
const [data, setData] = useRecoilState(dataState);
const [someDependency] = useRecoilState(someDependencyState);
useEffect(() => {
if(someDependency !== data) {
setData(someDependency);
}
}, [someDependency]);
return <></>;
};
export const App = () => (
<RecoilRoot>
<PageData />
<PageComponent />
</RecoilRoot>
);
```
### Use recoil family states and recoil family selectors
Recoil family states and selectors are a great way to avoid re-renders.
They are useful when you need to store a list of items.
### You shouldn't use `React.memo(MyComponent)`
Avoid using `React.memo()` because it does not solve the cause of the re-render, but instead breaks the re-render chain, which can lead to unexpected behavior and make the code very hard to refactor.
### Limit `useCallback` or `useMemo` usage
They are often not necessary and will make the code harder to read and maintain for a gain of performance that is unnoticeable.
## Console.logs
`console.log` statements are invaluable during development, offering real-time insights into variable values and code flow. But, leaving them in production code can lead to several issues:
1. **Performance**: Excessive logging can affect the runtime performance, specially on client-side applications.
2. **Security**: Logging sensitive data can expose critical information to anyone who inspects the browser's console.
3. **Cleanliness**: Filling up the console with logs can obscure important warnings or errors that developers or tools need to see.
4. **Professionalism**: End users or clients checking the console and seeing a myriad of log statements might question the code's quality and polish.
Make sure you remove all `console.logs` before pushing the code to production.
## Naming
### Variable Naming
Variable names ought to precisely depict the purpose or function of the variable.
#### The issue with generic names
Generic names in programming are not ideal because they lack specificity, leading to ambiguity and reduced code readability. Such names fail to convey the variable or function's purpose, making it challenging for developers to understand the code's intent without deeper investigation. This can result in increased debugging time, higher susceptibility to errors, and difficulties in maintenance and collaboration. Meanwhile, descriptive naming makes the code self-explanatory and easier to navigate, enhancing code quality and developer productivity.
```tsx
// ❌ Bad, uses a generic name that doesn't communicate its
// purpose or content clearly
const [value, setValue] = useState('');
```
```tsx
// ✅ Good, uses a descriptive name
const [email, setEmail] = useState('');
```
#### Some words to avoid in variable names
- dummy
### Event handlers
Event handler names should start with `handle`, while `on` is a prefix used to name events in components props.
```tsx
// ❌ Bad
const onEmailChange = (val: string) => {
// ...
};
```
```tsx
// ✅ Good
const handleEmailChange = (val: string) => {
// ...
};
```
## Optional Props
Avoid passing the default value for an optional prop.
**EXAMPLE**
Take the`EmailField` component defined below:
```tsx
type EmailFieldProps = {
value: string;
disabled?: boolean;
};
const EmailField = ({ value, disabled = false }: EmailFieldProps) => (
<TextInput value={value} disabled={disabled} fullWidth />
);
```
**Usage**
```tsx
// ❌ Bad, passing in the same value as the default value adds no value
const Form = () => <EmailField value="username@email.com" disabled={false} />;
```
```tsx
// ✅ Good, assumes the default value
const Form = () => <EmailField value="username@email.com" />;
```
## Component as props
Try as much as possible to pass uninstantiated components as props, so children can decide on their own of what props they need to pass.
The most common example for that is icon components:
```tsx
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;
// In MyComponent
const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
const theme = useTheme();
return (
<div>
<MyIcon size={theme.icon.size.md}>
</div>
)
};
```
For React to understand that the component is a component, you need to use PascalCase, to later instantiate it with `<MyIcon>`
## Prop Drilling: Keep It Minimal
Prop drilling, in the React context, refers to the practice of passing state variables and their setters through many component layers, even if intermediary components don't use them. While sometimes necessary, excessive prop drilling can lead to:
1. **Decreased Readability**: Tracing where a prop originates or where it's utilized can become convoluted in a deeply nested component structure.
2. **Maintenance Challenges**: Changes in one component's prop structure might require adjustments in several components, even if they don't directly use the prop.
3. **Reduced Component Reusability**: A component receiving a lot of props solely for passing them down becomes less general-purpose and harder to reuse in different contexts.
If you feel that you are using excessive prop drilling, see [state management best practices](/contributor/frontend/advanced/best-practices#state-management).
## Imports
When importing, opt for the designated aliases rather than specifying complete or relative paths.
**The Aliases**
```js
{
alias: {
"~": path.resolve(__dirname, "src"),
"@": path.resolve(__dirname, "src/modules"),
"@testing": path.resolve(__dirname, "src/testing"),
},
}
```
**Usage**
```tsx
// ❌ Bad, specifies the entire relative path
import {
CatalogDecorator
} from '../../../../../testing/decorators/CatalogDecorator';
import {
ComponentDecorator
} from '../../../../../testing/decorators/ComponentDecorator';
```
```tsx
// ✅ Good, utilises the designated aliases
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';=
```
## Schema Validation
[Zod](https://github.com/colinhacks/zod) is the schema validator for untyped objects:
```js
const validationSchema = z
.object({
exist: z.boolean(),
email: z
.string()
.email('Email must be a valid email'),
password: z
.string()
.regex(PASSWORD_REGEX, 'Password must contain at least 8 characters'),
})
.required();
type Form = z.infer<typeof validationSchema>;
```
## Breaking Changes
Always perform thorough manual testing before proceeding to guarantee that modifications havent caused disruptions elsewhere, given that tests have not yet been extensively integrated.

View File

@ -0,0 +1,23 @@
---
title: Hotkeys
sidebar_position: 11
sidebar_custom_props:
icon: TbKeyboard
---
You can intercept any hotkey combination and execute a custom action.
There's a thin wrapper on top of [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro) that makes it more performant and avoids unnecessary re-renders.
There's also a wrapper hook `useScopedHotkeys` that makes it easy to manage scopes.
```ts
useScopedHotkeys(
'ctrl+k,meta+k',
() => {
openCommandMenu();
},
AppHotkeyScope.CommandMenu,
[openCommandMenu],
);
```

View File

@ -0,0 +1,291 @@
---
title: Style Guide
sidebar_position: 4
sidebar_custom_props:
icon: TbPencil
---
This document includes the rules to follow when writing code.
The goal here is to have a consistent codebase, which is easy to read and easy to maintain.
For this, it's better to be a bit more verbose than to be too concise.
Always keep in mind that people read code more often than they write it, specially on an open source project, where anyone can contribute.
There are a lot of rules that are not defined here, but that are automatically checked by linters.
## React
### Use functional components
Always use TSX functional components.
Do not use default `import` with `const`, because it's harder to read and harder to import with code completion.
```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.
Use props destructuring.
```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>;
```
#### Refrain from using `React.FC` or `React.FunctionComponent` to define prop types
```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 />
);
```
#### No Single Variable Prop Spreading in JSX Elements
Avoid using single variable prop spreading in JSX elements, like `{...props}`. This practice often results in code that is less readable and harder to maintain because it's unclear which props the component is receiving.
```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 }} />;
};
```
Rationale:
- At a glance, it's clearer which props the code passes down, making it easier to understand and maintain.
- It helps to prevent tight coupling between components via their props.
- Linting tools make it easier to identify misspelled or unused props when you list props explicitly.
## JavaScript
### Use 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';
```
### Use optional chaining `?.`
```tsx
// ❌ Bad
onClick && onClick();
// ✅ Good
onClick?.();
```
## TypeScript
### Use `type` instead of `interface`
Always use `type` instead of `interface`, because they almost always overlap, and `type` is more flexible.
```tsx
// ❌ Bad
interface MyInterface {
name: string;
}
// ✅ Good
type MyType = {
name: string;
};
```
### Use string literals instead of enums
[String literals](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) are the go-to way to handle enum-like values in TypeScript. They are easier to extend with Pick and Omit, and offer a better developer experience, specially with code completion.
You can see why TypeScript recommends avoiding enums [here](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 and internal libraries
You should use enums that GraphQL codegen generates.
It's also better to use an enum when using an internal library, so the internal library doesn't have to expose a string literal type that is not related to the internal API.
Example:
```TSX
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
```
## Styling
### Use StyledComponents
Style the components with [styled-components](https://emotion.sh/docs/styled).
```tsx
// ❌ Bad
<div className="my-class">Hello World</div>
```
```tsx
// ✅ Good
const StyledTitle = styled.div`
color: red;
`;
```
Prefix styled components with "Styled" to differentiate them from "real" components.
```tsx
// ❌ Bad
const Title = styled.div`
color: red;
`;
```
```tsx
// ✅ Good
const StyledTitle = styled.div`
color: red;
`;
```
### Theming
Utilizing the theme for the majority of component styling is the preferred approach.
#### Units of measurement
Avoid using `px` or `rem` values directly within the styled components. The necessary values are generally already defined in the theme, so its recommended to make use of the theme for these purposes.
#### Colors
Refrain from introducing new colors; instead, use the existing palette from the theme. Should there be a situation where the palette does not align, please leave a comment so that the team can rectify it.
```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};
`;
```
## Enforcing No-Type Imports
Avoid type imports. To enforce this standard, an ESLint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code.
```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';
```
### Why No-Type Imports
- **Consistency**: By avoiding type imports and using a single approach for both type and value imports, the codebase remains consistent in its module import style.
- **Readability**: No-type imports improve code readability by making it clear when you're importing values or types. This reduces ambiguity and makes it easier to understand the purpose of imported symbols.
- **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code.
### ESLint Rule
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 itself discourages this practice, as mentioned in the [TypeScript 3.8 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports.
To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.

View File

@ -0,0 +1,4 @@
{
"label": "Basics",
"position": 1
}

View File

@ -0,0 +1,53 @@
---
title: Basics
sidebar_position: 0
---
import DocCardList from '@theme/DocCardList';
<DocCardList />
## Tech Stack
The project has a clean and simple stack, with minimal boilerplate code.
**App**
- [React](https://react.dev/)
- [Apollo](https://www.apollographql.com/docs/)
- [GraphQL Codegen](https://the-guild.dev/graphql/codegen)
- [Recoil](https://recoiljs.org/docs/introduction/core-concepts)
- [TypeScript](https://www.typescriptlang.org/)
**Testing**
- [Jest](https://jestjs.io/)
- [Storybook](https://storybook.js.org/)
**Tooling**
- [Yarn](https://yarnpkg.com/)
- [Craco](https://craco.js.org/docs/)
- [ESLint](https://eslint.org/)
## Architecture
### Routing
[React Router](https://reactrouter.com/) handles the routing.
To avoid unnecessary [re-renders](/contributor/frontend/advanced/best-practices#managing-re-renders) all the routing logic is in a `useEffect` in `PageChangeEffect`.
### State Management
[Recoil](https://recoiljs.org/docs/introduction/core-concepts) handles state management.
See [best practices](/contributor/frontend/advanced/best-practices#state-management) for more information on state management.
## Testing
[Jest](https://jestjs.io/) serves as the tool for unit testing while [Storybook](https://storybook.js.org/) is for component testing.
Jest is mainly for testing utility functions, and not components themselves.
Storybook is for testing the behavior of isolated components, as well as displaying the [design system](/contributor/frontend/basics/design-system).

View File

@ -0,0 +1,44 @@
---
title: Contributing
sidebar_position: 1
description: Learn how you can contribute to the project
sidebar_custom_props:
icon: TbTopologyStar
---
## Pre-requisites
Make sure that your [IDE is correctly setup](/contributor/local-setup/ide-setup) and that your backend is running on `localhost:3000`.
## Starting a new feature
Make sure your database is running on the URL provided in your `server/.env` file.
```bash
cd front
yarn
yarn start
```
## Regenerate graphql schema based on API graphql schema
```bash
yarn graphql:generate
```
## Lint
```bash
yarn lint
```
## Test
```bash
yarn test # run jest tests
yarn storybook:dev # run storybook
yarn storybook:test # run tests (needs yarn storybook:dev to be running)
yarn storybook:coverage # run tests (needs yarn storybook:dev to be running)
```

View File

@ -0,0 +1,10 @@
---
title: Design System
description: What our design system looks like
sidebar_position: 7
sidebar_custom_props:
icon: TbPaint
---
The CRM depends on its internal and custom design system, constructed on top of styled-components.

View File

@ -0,0 +1,113 @@
---
title: Folder Architecture
sidebar_position: 5
description: A detailed look into our folder architecture
sidebar_custom_props:
icon: TbFolder
---
In this guide, you will explore the details of the project directory structure and how it contributes to the organization and maintainability of Twenty.
By following this folder architecture convention, it's easier to find the files related to specific features and ensure that the application is scalable and maintainable.
```
front
└───modules
│ └───module1
│ │ └───submodule1
│ └───module2
│ └───ui
│ │ └───display
│ │ └───inputs
│ │ │ └───buttons
│ │ └───...
└───pages
└───...
```
## Pages
Includes the top-level components defined by the application routes. They import more low-level components from the modules folder (more details below).
## Modules
Each module represents a feature or a group of feature, comprising its specific components, states, and operational logic.
They should all follow the structure below. You can nest modules within modules (referred to as submodules) and the same rules will apply.
```
module1
└───components
│ └───component1
│ └───component2
└───constants
└───contexts
└───graphql
│ └───fragments
│ └───queries
│ └───mutations
└───hooks
│ └───internal
└───states
│ └───selectors
└───types
└───utils
```
### Contexts
A context is a way to pass data through the component tree without having to pass props down manually at every level.
See [React Context](https://react.dev/reference/react#context-hooks) for more details.
### GraphQL
Includes fragments, queries, and mutations.
See [GraphQL](https://graphql.org/learn/) for more details.
- Fragments
A fragment is a reusable piece of a query, which you can use in different places. By using fragments, it's easier to avoid duplicating code.
See [GraphQL Fragments](https://graphql.org/learn/queries/#fragments) for more details.
- Queries
See [GraphQL Queries](https://graphql.org/learn/queries/) for more details.
- Mutations
See [GraphQL Mutations](https://graphql.org/learn/queries/#mutations) for more details.
### Hooks
See [Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks) for more details.
### States
Contains the state management logic. [RecoilJS](https://recoiljs.org) handles this.
- Selectors: See [RecoilJS Selectors](https://recoiljs.org/docs/basic-tutorial/selectors) for more details.
React's built-in state management still handles state within a component.
### Utils
Should just contain reusable pure functions. Otherwise, create custom hooks in the `hooks` folder.
## UI
Contains all the reusable UI components used in the application.
This folder can contain sub-folders, like `data`, `display`, `feedback`, and `input` for specific types of components. Each component should be self-contained and reusable, so that you can use it in different parts of the application.
By separating the UI components from the other components in the `modules` folder, it's easier to maintain a consistent design and to make changes to the UI without affecting other parts (business logic) of the codebase.
## Interface and dependencies
You can import other module code from any module except for the `ui` folder. This will keep its code easy to test.
### Internal
Each part (hooks, states, ...) of a module can have an `internal` folder, which contains parts that are just used within the module.

View File

@ -0,0 +1,65 @@
---
title: Work with Figma
description: Learn how you can collaborate with Twenty's Figma
sidebar_position: 2
sidebar_custom_props:
icon: TbBrandFigma
---
Figma is a collaborative interface design tool that aids in bridging the communication barrier between designers and developers.
This guide explains how you can collaborate with Figma.
## Access
1. **Access the shared link:** You can access the project's Figma file [here](https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty).
2. **Sign in:** If you're not already signed in, Figma will prompt you to do so.
Key features are only available to logged-in users, such as the developer mode and the ability to select a dedicated frame.
:::caution Note
You will not be able to collaborate effectively without an account.
:::
## Figma structure
On the left sidebar, you can access the different pages of Twenty's Figma. This is how they're organized:
- **Components page:** This is the first page. The designer uses it to create and organize the reusable design elements used throughout the design file. For example, buttons, icons, symbols, or any other reusable components. It serves to maintain consistency across the design.
- **Main page:** The second page is the main page, which shows the complete user interface of the project. You can press ***Play*** to use the full app prototype.
- **Features pages:** The other pages are typically dedicated to features in progress. They contain the design of specific features or modules of the application or website. They are typically still in progress.
## Useful Tips
With read-only access, you can't edit the design but you can access all features that will be useful to convert the designs into code.
### Use the Dev mode
Figma's Dev Mode enhances developers' productivity by providing easy design navigation, effective asset management, efficient communication tools, toolbox integrations, quick code snippets, and key layer information, bridging the gap between design and development. You can learn more about Dev Mode [here](https://www.figma.com/dev-mode/).
Switch to the "Developer" mode in the right part of the toolbar to see design specs, copy CSS, and access assets.
### Use the Prototype
Click on any element on the canvas and press the “Play” button at the top right edge of the interface to access the prototype view. Prototype mode allows you to interact with the design as if it were the final product. It demonstrates the flow between screens and how interface elements like buttons, links, or menus behave when interacted with.
1. **Understanding transitions and animations:** In the Prototype mode, you can view any transitions or animations added by a designer between screens or UI elements, providing clear visual instructions to developers on the intended behavior and style.
2. **Implementation clarification:** A prototype can also help reduce ambiguities. Developers can interact with it to gain a better understanding of the functionality or appearance of particular elements.
For more comprehensive details and guidance on learning the Figma platform, you can visit the official [Figma Documentation](https://help.figma.com/hc/en-us).
### Measure distances
Select an element, hold `Option` key (Mac) or `Alt` key (Windows), then hover over another element to see the distance between them.
### Figma extension for VSCode (Recommended)
[Figma for VS Code](https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension)
lets you navigate and inspect design files, collaborate with designers, track changes, and speed up implementation - all without leaving your text editor.
It's part of our recommended extensions.
## Collaboration
1. **Using Comments:** You are welcome to use the comment feature by clicking on the bubble icon in the left part of the toolbar.
2. **Cursor chat:** A nice feature of Figma is the Cursor chat. Just press `;` on Mac and `/` on Windows to send a message if you see someone else using Figma as the same time as you.

View File

@ -0,0 +1,14 @@
---
id: frontend
title: Frontend Development
displayed_sidebar: frontendSidebar
sidebar_position: 0
sidebar_custom_props:
icon: TbTerminal2
isSidebarRoot: true
---
Welcome to the Frontend Development section of the documentation.
Here you will find information about the frontend development process, the recommended tools, and the best practices you should follow.

View File

@ -0,0 +1,4 @@
{
"label": "UI Components",
"position": 1
}

View File

@ -0,0 +1,9 @@
{
"label": "Display",
"position": 1,
"collapsible": true,
"collapsed": false,
"customProps": {
"icon": "TbAppWindow"
}
}

View File

@ -0,0 +1,139 @@
---
title: App Tooltip
sidebar_position: 6
sidebar_custom_props:
icon: TbTooltip
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import appTooltipCode from '!!raw-loader!@site/src/ui/display/appTooltipCode.js'
import overflowingTextWithTooltipCode from '!!raw-loader!@site/src/ui/display/overflowingTextWithTooltipCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
A brief message that displays additional information when a user interacts with an element.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/tooltip/AppTooltip']}
componentCode={appTooltipCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional CSS class for additional styling</td>
</tr>
<tr>
<td>anchorSelect</td>
<td>CSS selector</td>
<td>Selector for the tooltip anchor (the element that triggers the tooltip)</td>
</tr>
<tr>
<td>content</td>
<td>string</td>
<td>The content you want to display within the tooltip</td>
</tr>
<tr>
<td>delayHide</td>
<td>number</td>
<td>The delay in seconds before hiding the tooltip after the cursor leaves the anchor</td>
</tr>
<tr>
<td>offset</td>
<td>number</td>
<td>The offset in pixels for positioning the tooltip</td>
</tr>
<tr>
<td>noArrow</td>
<td>boolean</td>
<td>If `true`, hides the arrow on the tooltip</td>
</tr>
<tr>
<td>isOpen</td>
<td>boolean</td>
<td>If `true`, the tooltip is open by default</td>
</tr>
<tr>
<td>place</td>
<td>`PlacesType` string from `react-tooltip`</td>
<td>Specifies the placement of the tooltip. Values include `bottom`, `left`, `right`, `top`, `top-start`, `top-end`, `right-start`, `right-end`, `bottom-start`, `bottom-end`, `left-start`, and `left-end`</td>
</tr>
<tr>
<td>positionStrategy</td>
<td>`PositionStrategy` string from `react-tooltip`</td>
<td>Position strategy for the tooltip. Has two values: `absolute` and `fixed`</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Overflowing Text with Tooltip
Handles overflowing text and displays a tooltip when the text overflows.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/tooltip/OverflowingTextWithTooltip']}
componentCode={overflowingTextWithTooltipCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>text</td>
<td>string</td>
<td>The content you want to display in the overflowing text area</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,95 @@
---
title: Checkmark
sidebar_position: 1
sidebar_custom_props:
icon: TbCheck
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import checkmarkCode from '!!raw-loader!@site/src/ui/display/checkmarkCode.js'
import animatedCheckmarkCode from '!!raw-loader!@site/src/ui/display/animatedCheckmarkCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
Represents a successful or completed action.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/checkmark/components/Checkmark']}
componentCode={checkmarkCode}
/>
</TabItem>
<TabItem value="props" label="Props">
Extends `React.ComponentPropsWithoutRef<'div'>` and accepts all the props of a regular `div` element.
</TabItem >
</Tabs>
## Animated Checkmark
Represents a checkmark icon with the added feature of animation.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/checkmark/components/AnimatedCheckmark']}
componentCode={animatedCheckmarkCode}
/>
</TabItem>
<TabItem value="props" label="Props" default>
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>isAnimating</td>
<td>boolean</td>
<td>Controls whether the checkmark is animating</td>
<td>`false`</td>
</tr>
<tr>
<td>color</td>
<td>string</td>
<td>Color of the checkmark</td>
<td>Theme's gray0</td>
</tr>
<tr>
<td>duration</td>
<td>number</td>
<td>The duration of the animation in seconds</td>
<td>0.5 seconds</td>
</tr>
<tr>
<td>size</td>
<td>number</td>
<td>The size of the checkmark</td>
<td>28 pixels</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,252 @@
---
title: Chip
sidebar_position: 2
sidebar_custom_props:
icon: TbLayoutList
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import chipCode from '!!raw-loader!@site/src/ui/display/chipCode.js'
import entityChipCode from '!!raw-loader!@site/src/ui/display/entityChipCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
A visual element that you can use as a clickable or non-clickable container with a label, optional left and right components, and various styling options to display labels and tags.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']}
componentCode={chipCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>size</td>
<td>`ChipSize` enum</td>
<td>Specifies the size of the chip. Has two options: `large` and `small`</td>
<td>small</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Indicates whether the chip is disabled</td>
<td>false</td>
</tr>
<tr>
<td>clickable</td>
<td>boolean</td>
<td>Specifies whether the chip is clickable</td>
<td>true</td>
</tr>
<tr>
<td>label</td>
<td>string</td>
<td>Represents the text content or label inside the chip</td>
<td></td>
</tr>
<tr>
<td>maxWidth</td>
<td>string</td>
<td>Specifies the maximum width of the chip</td>
<td>200px</td>
</tr>
<tr>
<td>variant</td>
<td>`ChipVariant` enum</td>
<td>Specifies the visual style or variant of the chip. Has four options: `regular`, `highlighted`, `transparent`, and `rounded`</td>
<td>regular</td>
</tr>
<tr>
<td>accent</td>
<td>`ChipAccent` enum</td>
<td>Determines the text color or accent color of the chip. Has two options: `text-primary` and `text-secondary`</td>
<td>text-primary</td>
</tr>
<tr>
<td>leftComponent</td>
<td>`React.ReactNode`</td>
<td>An optional React/node component that you can place on the left side of the chip</td>
<td></td>
</tr>
<tr>
<td>rightComponent</td>
<td>`React.ReactNode`</td>
<td>An optional React/node component that you can place on the right side of the chip</td>
<td></td>
</tr>
<tr>
<td>className</td>
<td>string</td>
<td>An optional class name to apply additional custom styles to the chip</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Examples
### Transparent Disabled Chip
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']}
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip";
export const MyComponent = () => {
return (
<Chip
size="large"
label="Transparent Disabled Chip"
clickable={false}
variant="rounded"
accent="text-secondary"
leftComponent
rightComponent
maxWidth="200px"
className
/>
);
};
`}
/>
<br/>
### Disabled Chip with Tooltip
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']}
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip";
export const MyComponent = () => {
return (
<Chip
size="large"
label="This is a very long label for a disabled chip that triggers a tooltip when overflowing."
clickable={false}
variant="regular"
accent="text-primary"
leftComponent
rightComponent
maxWidth="200px"
className
/>
);
};
`}
/>
## Entity Chip
A Chip-like element to display information about an entity.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/EntityChip', '@/ui/display/icon/types/IconComponent']}
componentCode={entityChipCode}
/>
</TabItem >
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>linkToEntity</td>
<td>string</td>
<td>The link to the entity</td>
<td></td>
</tr>
<tr>
<td>entityId</td>
<td>string</td>
<td>The unique identifier for the entity</td>
<td></td>
</tr>
<tr>
<td>name</td>
<td>string</td>
<td>The name of the entity</td>
<td></td>
</tr>
<tr>
<td>pictureUrl</td>
<td>string</td>
<td>The URL of the entity's picture</td>
<td></td>
</tr>
<tr>
<td>avatarType</td>
<td>Avatar Type</td>
<td>The type of avatar you want to display. Has two options: `rounded` and `squared`</td>
<td>rounded</td>
</tr>
<tr>
<td>variant</td>
<td>`EntityChipVariant` enum</td>
<td>Variant of the entity chip you want to display. Has two options: `regular` and `transparent`</td>
<td>regular</td>
</tr>
<tr>
<td>LeftIcon</td>
<td>IconComponent</td>
<td>A React component representing an icon. Displayed on the left side of the chip</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,134 @@
---
title: Icons
sidebar_position: 3
sidebar_custom_props:
icon: TbIcons
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import tablerIconExampleCode from '!!raw-loader!@site/src/ui/display/tablerIconExampleCode.js'
import iconAddressBookCode from '!!raw-loader!@site/src/ui/display/iconAddressBookCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
A list of icons used throughout our app.
## Tabler Icons
We use Tabler icons for React throughout the app.
<Tabs>
<TabItem value="installation" label="Installation">
```
yarn add @tabler/icons-react
```
</TabItem>
<TabItem value="usage" label="Usage" default>
You can import each icon as a component. Here's an example:
<SandpackEditor
availableComponentPaths={['@/ui/display/icon/components/IconAddressBook']}
componentCode={tablerIconExampleCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>size</td>
<td>number</td>
<td>The height and width of the icon in pixels</td>
<td>24</td>
</tr>
<tr>
<td>color</td>
<td>string</td>
<td>The color of the icons</td>
<td>currentColor</td>
</tr>
<tr>
<td>stroke</td>
<td>number</td>
<td>The stroke width of the icon in pixels</td>
<td>2</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Custom Icons
In addition to Tabler icons, the app also uses some custom icons.
### Icon Address Book
Displays an address book icon.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/icon/components/IconAddressBook']}
componentCode={iconAddressBookCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>size</td>
<td>number</td>
<td>The height and width of the icon in pixels</td>
<td>24</td>
</tr>
<tr>
<td>stroke</td>
<td>number</td>
<td>The stroke width of the icon in pixels</td>
<td>2</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,49 @@
---
title: Soon Pill
sidebar_position: 4
sidebar_custom_props:
icon: TbPill
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import soonPillCode from '!!raw-loader!@site/src/ui/display/soonPillCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
A small badge or "pill" to indicate something is coming soon.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/pill/components/SoonPill']}
componentCode={soonPillCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,68 @@
---
title: Tag
sidebar_position: 5
sidebar_custom_props:
icon: TbTag
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import tagCode from '!!raw-loader!@site/src/ui/display/tagCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
Component to visually categorize or label content.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/display/tag/components/Tag']}
componentCode={tagCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
</tr>
<tr>
<td>color</td>
<td>string</td>
<td>Color of the tag. Options include: `green`, `turquoise`, `sky`, `blue`, `purple`, `pink`, `red`, `orange`, `yellow`, `gray`</td>
</tr>
<tr>
<td>text</td>
<td>string</td>
<td>The content of the tag</td>
</tr>
<tr>
<td>onClick</td>
<td>function</td>
<td>Optional function called when a user clicks on the tag</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,9 @@
{
"label": "Feedback",
"position": 2,
"collapsible": true,
"collapsed": false,
"customProps": {
"icon": "TbForms"
}
}

View File

@ -0,0 +1,143 @@
---
title: Progress Bar
sidebar_position: 1
sidebar_custom_props:
icon: TbLoader2
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import progressBarCode from '!!raw-loader!@site/src/ui/feedback/progressBarCode.js'
import circularProgressBarCode from '!!raw-loader!@site/src/ui/feedback/circularProgressBarCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
Indicates progress or countdown and moves from right to left.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/feedback/progress-bar/components/ProgressBar']}
componentCode={progressBarCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>duration</td>
<td>number</td>
<td>The total duration of the progress bar animation in milliseconds</td>
<td>3</td>
</tr>
<tr>
<td>delay</td>
<td>number</td>
<td>The delay in starting the progress bar animation in milliseconds</td>
<td>0</td>
</tr>
<tr>
<td>easing</td>
<td>string</td>
<td>Easing function for the progress bar animation</td>
<td>easeInOut</td>
</tr>
<tr>
<td>barHeight</td>
<td>number</td>
<td>The height of the bar in pixels</td>
<td>24</td>
</tr>
<tr>
<td>barColor</td>
<td>string</td>
<td>The color of the bar</td>
<td>gray80</td>
</tr>
<tr>
<td>autoStart</td>
<td>boolean</td>
<td>If `true`, the progress bar animation starts automatically when the component mounts</td>
<td>`true`</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Circular Progress Bar
Indicates the progress of a task, often used in loading screens or areas where you want to communicate ongoing processes to the user.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/feedback/progress-bar/components/CircularProgressBar']}
componentCode={circularProgressBarCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>size</td>
<td>number</td>
<td>The size of the circular progress bar</td>
<td>50</td>
</tr>
<tr>
<td>barWidth</td>
<td>number</td>
<td>The width of the progress bar line</td>
<td>5</td>
</tr>
<tr>
<td>barColor</td>
<td>string</td>
<td>The color of the progress bar</td>
<td>currentColor</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,9 @@
{
"label": "Input",
"position": 3,
"collapsible": true,
"collapsed": false,
"customProps": {
"icon": "TbInputSearch"
}
}

View File

@ -0,0 +1,798 @@
---
title: Buttons
sidebar_position: 1
sidebar_custom_props:
icon: TbSquareRoundedPlusFilled
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import buttonCode from '!!raw-loader!@site/src/ui/input/button/buttonCode.js'
import buttonGroupCode from '!!raw-loader!@site/src/ui/input/button/buttonGroupCode.js'
import floatingButtonCode from '!!raw-loader!@site/src/ui/input/button/floatingButtonCode.js'
import floatingButtonGroupCode from '!!raw-loader!@site/src/ui/input/button/floatingButtonGroupCode.js'
import floatingIconButtonCode from '!!raw-loader!@site/src/ui/input/button/floatingIconButtonCode.js'
import floatingIconButtonGroupCode from '!!raw-loader!@site/src/ui/input/button/floatingIconButtonGroupCode.js'
import lightButtonCode from '!!raw-loader!@site/src/ui/input/button/lightButtonCode.js'
import lightIconButtonCode from '!!raw-loader!@site/src/ui/input/button/lightIconButtonCode.js'
import mainButtonCode from '!!raw-loader!@site/src/ui/input/button/mainButtonCode.js'
import roundedIconButtonCode from '!!raw-loader!@site/src/ui/input/button/roundedIconButtonCode.js'
A list of buttons and button groups used throughout the app.
## Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/Button']}
componentCode={buttonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional class name for additional styling</td>
<td></td>
</tr>
<tr>
<td>Icon</td>
<td>`React.ComponentType`</td>
<td>An optional icon component that's displayed within the button</td>
<td></td>
</tr>
<tr>
<td>title</td>
<td>string</td>
<td>The text content of the button</td>
<td></td>
</tr>
<tr>
<td>fullWidth</td>
<td>boolean</td>
<td>Defines whether the button should span the whole width of its container</td>
<td>`false`</td>
</tr>
<tr>
<td>variant</td>
<td>string</td>
<td>The visual style variant of the button. Options include `primary`, `secondary`, and `tertiary`</td>
<td>primary</td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the button. Has two options: `small` and `medium`</td>
<td>medium</td>
</tr>
<tr>
<td>position</td>
<td>string</td>
<td>The position of the button in relation to its siblings. Options include: `standalone`, `left`, `right`, and `middle`</td>
<td>standalone</td>
</tr>
<tr>
<td>accent</td>
<td>string</td>
<td>The accent color of the button. Options include: `default`, `blue`, and `danger`</td>
<td>default</td>
</tr>
<tr>
<td>soon</td>
<td>boolean</td>
<td>Indicates if the button is marked as "soon" (such as for upcoming features)</td>
<td>`false`</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Specifies whether button is disabled or not</td>
<td>`false`</td>
</tr>
<tr>
<td>focus</td>
<td>boolean</td>
<td>Determines if the button has focus</td>
<td>`false`</td>
</tr>
<tr>
<td>onClick</td>
<td>function</td>
<td>A callback function that triggers when the user clicks on the button</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Button Group
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/Button', '@/ui/input/button/components/ButtonGroup']}
componentCode={buttonGroupCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>variant</td>
<td>string</td>
<td>The visual style variant of the buttons within the group. Options include `primary`, `secondary`, and `tertiary`</td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the buttons within the group. Has two options: `medium` and `small`</td>
</tr>
<tr>
<td>accent</td>
<td>string</td>
<td>The accent color of the buttons within the group. Options include `default`, `blue` and `danger`</td>
</tr>
<tr>
<td>className</td>
<td>string</td>
<td>Optional class name for additional styling</td>
</tr>
<tr>
<td>children</td>
<td>ReactNode</td>
<td>An array of React elements representing the individual buttons within the group</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Floating Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/FloatingButton']}
componentCode={floatingButtonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
<td></td>
</tr>
<tr>
<td>Icon</td>
<td>`React.ComponentType`</td>
<td>An optional icon component that's displayed within the button</td>
<td></td>
</tr>
<tr>
<td>title</td>
<td>string</td>
<td>The text content of the button</td>
<td></td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the button. Has two options: `small` and `medium`</td>
<td>small</td>
</tr>
<tr>
<td>position</td>
<td>string</td>
<td>The position of the button in relation to its sublings. Options include: `standalone`, `left`, `middle`, `right`</td>
<td></td>
</tr>
<tr>
<td>applyShadow</td>
<td>boolean</td>
<td>Determines whether to apply shadow to a button</td>
<td>`true`</td>
</tr>
<tr>
<td>applyBlur</td>
<td>boolean</td>
<td>Determines whether to apply a blur effect to the button</td>
<td>`true`</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Determines whether the button is disabled</td>
<td>`false`</td>
</tr>
<tr>
<td>focus</td>
<td>boolean</td>
<td>Indicates if the button has focus</td>
<td>`false`</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Floating Button Group
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/FloatingButton', '@/ui/input/button/components/FloatingButtonGroup']}
componentCode={floatingButtonGroupCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the button. Has two options: `small` and `medium`</td>
<td>small</td>
</tr>
<tr>
<td>children</td>
<td>ReactNode</td>
<td>An array of React elements representing the individual buttons within the group</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Floating Icon Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/FloatingIconButton']}
componentCode={floatingIconButtonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
<td></td>
</tr>
<tr>
<td>Icon</td>
<td>`React.ComponentType`</td>
<td>An optional icon component that's displayed within the button</td>
<td></td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the button. Has two options: `small` and `medium`</td>
<td>small</td>
</tr>
<tr>
<td>position</td>
<td>string</td>
<td>The position of the button in relation to its siblings. Options include: `standalone`, `left`, `right`, and `middle`</td>
<td>standalone</td>
</tr>
<tr>
<td>applyShadow</td>
<td>boolean</td>
<td>Determines whether to apply shadow to a button</td>
<td>`true`</td>
</tr>
<tr>
<td>applyBlur</td>
<td>boolean</td>
<td>Determines whether to apply a blur effect to the button</td>
<td>`true`</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Determines whether the button is disabled</td>
<td>`false`</td>
</tr>
<tr>
<td>focus</td>
<td>boolean</td>
<td>Indicates if the button has focus</td>
<td>`false`</td>
</tr>
<tr>
<td>onClick</td>
<td>function</td>
<td>A callback function that triggers when the user clicks on the button</td>
<td></td>
</tr>
<tr>
<td>isActive</td>
<td>boolean</td>
<td>Determines if the button is in an active state</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Floating Icon Button Group
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/FloatingIconButtonGroup']}
componentCode={floatingIconButtonGroupCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the button. Has two options: `small` and `medium`</td>
</tr>
<tr>
<td>iconButtons</td>
<td>array</td>
<td>An array of objects, each representing an icon button in the group. Each object should include the icon component you want to display in the button, the function you want to call when a user clicks on the button, and whether the button should be active or not.</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Light Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/LightButton']}
componentCode={lightButtonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
<td></td>
</tr>
<tr>
<td>icon</td>
<td>`React.ReactNode`</td>
<td>The icon you want to display in the button</td>
<td></td>
</tr>
<tr>
<td>title</td>
<td>string</td>
<td>The text content of the button</td>
<td></td>
</tr>
<tr>
<td>accent</td>
<td>string</td>
<td>The accent color of the button. Options include: `secondary` and `tertiary`</td>
<td>secondary</td>
</tr>
<tr>
<td>active</td>
<td>boolean</td>
<td>Determines if the button is in an active state</td>
<td>`false`</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Determines whether the button is disabled</td>
<td>`false`</td>
</tr>
<tr>
<td>focus</td>
<td>boolean</td>
<td>Indicates if the button has focus</td>
<td>`false`</td>
</tr>
<tr>
<td>onClick</td>
<td>function</td>
<td>A callback function that triggers when the user clicks on the button</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Light Icon Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/LightIconButton']}
componentCode={lightIconButtonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
<td></td>
</tr>
<tr>
<td>testId</td>
<td>string</td>
<td>Test identifier for the button</td>
<td></td>
</tr>
<tr>
<td>Icon</td>
<td>`React.ComponentType`</td>
<td>An optional icon component that's displayed within the button</td>
<td></td>
</tr>
<tr>
<td>title</td>
<td>string</td>
<td>The text content of the button</td>
<td></td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the button. Has two options: `small` and `medium`</td>
<td>small</td>
</tr>
<tr>
<td>accent</td>
<td>string</td>
<td>The accent color of the button. Options include: `secondary` and `tertiary`</td>
<td>secondary</td>
</tr>
<tr>
<td>active</td>
<td>boolean</td>
<td>Determines if the button is in an active state</td>
<td>`false`</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Determines whether the button is disabled</td>
<td>`false`</td>
</tr>
<tr>
<td>focus</td>
<td>boolean</td>
<td>Indicates if the button has focus</td>
<td>`false`</td>
</tr>
<tr>
<td>onClick</td>
<td>function</td>
<td>A callback function that triggers when the user clicks on the button</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Main Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/MainButton']}
componentCode={mainButtonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>title</td>
<td>string</td>
<td>The text content of the button</td>
<td></td>
</tr>
<tr>
<td>fullWidth</td>
<td>boolean</td>
<td>efines whether the button should span the whole width of its container</td>
<td>`false`</td>
</tr>
<tr>
<td>variant</td>
<td>string</td>
<td>The visual style variant of the button. Options include `primary` and `secondary`</td>
<td>primary</td>
</tr>
<tr>
<td>soon</td>
<td>boolean</td>
<td>Indicates if the button is marked as "soon" (such as for upcoming features)</td>
<td>`false`</td>
</tr>
<tr>
<td>Icon</td>
<td>`React.ComponentType`</td>
<td>An optional icon component that's displayed within the button</td>
<td></td>
</tr>
<tr>
<td>React `button` props</td>
<td>`React.ComponentProps<'button'>`</td>
<td>Additional props from React's `button` element</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Rounded Icon Button
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/button/components/RoundedIconButton']}
componentCode={roundedIconButtonCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>Icon</td>
<td>`React.ComponentType`</td>
<td>An optional icon component that's displayed within the button</td>
<td></td>
</tr>
<tr>
<td>React `button` props</td>
<td>`React.ButtonHTMLAttributes<HTMLButtonElement>`</td>
<td>Additional props from React's `button` element</td>
<td></td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,93 @@
---
title: Checkbox
sidebar_position: 4
sidebar_custom_props:
icon: TbCheckbox
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import checkboxCode from '!!raw-loader!@site/src/ui/input/components/checkboxCode.js'
Used when a user needs to select multiple values from several options.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/Checkbox']}
componentCode={checkboxCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>checked</td>
<td>boolean</td>
<td>Indicates whether the checkbox is checked</td>
<td></td>
</tr>
<tr>
<td>indeterminate</td>
<td>boolean</td>
<td>Indicates whether the checkbox is in an indeterminate state (neither checked nor unchecked)</td>
<td></td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The callback function you want to trigger when the checkbox state changes</td>
<td></td>
</tr>
<tr>
<td>onCheckedChange</td>
<td>function</td>
<td>The callback function you want to trigger when the `checked` state changes</td>
<td></td>
</tr>
<tr>
<td>variant</td>
<td>string</td>
<td>The visual style variant of the box. Options include: `primary`, `secondary`, and `tertiary`</td>
<td>primary</td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the checkbox. Has two options: `small` and `large`</td>
<td>small</td>
</tr>
<tr>
<td>shape</td>
<td>string</td>
<td>The shape of the checkbox. Has two options: `squared` and `rounded`</td>
<td>squared</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,111 @@
---
title: Color Scheme
sidebar_position: 2
sidebar_custom_props:
icon: TbColorFilter
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import colorSchemeCardCode from '!!raw-loader!@site/src/ui/input/color-scheme/colorSchemeCardCode.js'
import colorSchemePickerCode from '!!raw-loader!@site/src/ui/input/color-scheme/colorSchemePickerCode.js'
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
## Color Scheme Card
Represents different color schemes and is specially tailored for light and dark themes.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/color-scheme/components/ColorSchemeCard']}
componentCode={colorSchemeCardCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>variant</td>
<td>string</td>
<td>The color scheme variant. Options include `Dark`, `Light`, and `System`</td>
<td>light</td>
</tr>
<tr>
<td>selected</td>
<td>boolean</td>
<td>If `true`, displays a checkmark to indicate the selected color scheme</td>
</tr>
<tr>
<td>additional props</td>
<td>`React.ComponentPropsWithoutRef<'div'>`</td>
<td>Standard HTML `div` element props</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Color Scheme Picker
Allows users to choose between different color schemes.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/color-scheme/components/ColorSchemePicker']}
componentCode={colorSchemePickerCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>value</td>
<td>`Color Scheme`</td>
<td>The currently selected color scheme</td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The callback function you want to trigger when a user selects a color scheme</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,92 @@
---
title: Icon Picker
sidebar_position: 5
sidebar_custom_props:
icon: TbColorPicker
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import iconPickerCode from '!!raw-loader!@site/src/ui/input/components/iconPickerCode.js'
A dropdown-based icon picker that allows users to select an icon from a list.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/IconPicker']}
componentCode={iconPickerCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Disables the icon picker if set to `true`</td>
<td></td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The callback function triggered when the user selects an icon. It receives an object with `iconKey` and `Icon` properties</td>
<td></td>
</tr>
<tr>
<td>selectedIconKey</td>
<td>string</td>
<td>The key of the initially selected icon</td>
<td></td>
</tr>
<tr>
<td>onClickOutside</td>
<td>function</td>
<td>Callback function triggered when the user clicks outside the dropdown</td>
<td></td>
</tr>
<tr>
<td>onClose</td>
<td>function</td>
<td>Callback function triggered when the dropdown is closed</td>
<td></td>
</tr>
<tr>
<td>onOpen</td>
<td>function</td>
<td>Callback function triggered when the dropdown is opened</td>
<td></td>
</tr>
<tr>
<td>variant</td>
<td>string</td>
<td>The visual style variant of the clickable icon. Options include: `primary`, `secondary`, and `tertiary`</td>
<td>secondary</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,92 @@
---
title: Image Input
sidebar_position: 6
sidebar_custom_props:
icon: TbUpload
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import imageInputCode from '!!raw-loader!@site/src/ui/input/components/imageInputCode.js'
Allows users to upload and remove an image.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/ImageInput']}
componentCode={imageInputCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>picture</td>
<td>string</td>
<td>The image source URL</td>
<td></td>
</tr>
<tr>
<td>onUpload</td>
<td>function</td>
<td>The function called when a user uploads a new image. It receives the `File` object as a parameter</td>
<td></td>
</tr>
<tr>
<td>onRemove</td>
<td>function</td>
<td>The function called when the user clicks on the remove button</td>
<td></td>
</tr>
<tr>
<td>onAbort</td>
<td>function</td>
<td>The function called when a user clicks on the abort button during image upload</td>
<td></td>
</tr>
<tr>
<td>isUploading</td>
<td>boolean</td>
<td>Indicates whether an image is currently being uploaded</td>
<td>`false`</td>
</tr>
<tr>
<td>errorMessage</td>
<td>string</td>
<td>An optional error message to display below the image input</td>
<td></td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>If `true`, the entire input is disabled, and the buttons are not clickable</td>
<td>`false`</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,164 @@
---
title: Radio
sidebar_position: 7
sidebar_custom_props:
icon: TbCircleDot
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import radioCode from '!!raw-loader!@site/src/ui/input/components/radioCode.js'
import radioGroupCode from '!!raw-loader!@site/src/ui/input/components/radioGroupCode.js'
Used when users may only choose one option from a series of options.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/Radio']}
componentCode={radioCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>style</td>
<td>`React.CSS` properties</td>
<td>Additional inline styles for the component</td>
<td></td>
</tr>
<tr>
<td>className</td>
<td>string</td>
<td>Optional CSS class for additional styling</td>
<td></td>
</tr>
<tr>
<td>checked</td>
<td>boolean</td>
<td>Indicates whether the radio button is checked</td>
<td></td>
</tr>
<tr>
<td>value</td>
<td>string</td>
<td>The label or text associated with the radio button</td>
<td></td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The function called when the selected radio button is changed</td>
<td></td>
</tr>
<tr>
<td>onCheckedChange</td>
<td>function</td>
<td>The function called when the `checked` state of the radio button changes</td>
<td></td>
</tr>
<tr>
<td>size</td>
<td>string</td>
<td>The size of the radio button. Options include: `large` and `small`</td>
<td>small</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>If `true`, the radio button is disabled and not clickable</td>
<td>false</td>
</tr>
<tr>
<td>labelPosition</td>
<td>string</td>
<td>The position of the label text relative to the radio button. Has two options: `left` and `right`</td>
<td>right</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Radio Group
Groups together related radio buttons.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/RadioGroup', '@/ui/input/components/Radio']}
componentCode={radioGroupCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>value</td>
<td>string</td>
<td>The value of the currently selected radio button</td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The callback function triggered when the radio button is changed</td>
</tr>
<tr>
<td>onValueChange</td>
<td>function</td>
<td>The callback function triggered when the selected value in the group changes.</td>
</tr>
<tr>
<td>children</td>
<td>`React.ReactNode`</td>
<td>Allows you to pass React components (such as Radio) as children to the Radio Group</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,85 @@
---
title: Select
sidebar_position: 8
sidebar_custom_props:
icon: TbSelect
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import selectCode from '!!raw-loader!@site/src/ui/input/components/selectCode.js'
Allows users to pick a value from a list of predefined options.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/Select', '@/ui/display/icon/types/IconComponent']}
componentCode={selectCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional CSS class for additional styling</td>
</tr>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>When set to `true`, disables user interaction with the component</td>
</tr>
<tr>
<td>dropdownScopeId</td>
<td>string</td>
<td>Required prop that uniquely identifies the dropdown scope</td>
</tr>
<tr>
<td>label</td>
<td>string</td>
<td>The label to describe the purpose of the `Select` component</td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The function called when the selected values change</td>
</tr>
<tr>
<td>options</td>
<td>array</td>
<td>Represents the options available for the `Selected` component. It's an array of objects where each object has a `value` (the unique identifier), `label` (the unique identifier), and an optional `Icon`</td>
</tr>
<tr>
<td>value</td>
<td>string</td>
<td>Represents the currently selected value. It should match one of the `value` properties in the `options` array</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,322 @@
---
title: Text
sidebar_position: 3
sidebar_custom_props:
icon: TbTextSize
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import textInputCode from '!!raw-loader!@site/src/ui/input/components/textInputCode.js'
import autosizeTextInputCode from '!!raw-loader!@site/src/ui/input/components/autosizeTextInputCode.js'
import entityTitleDoubleTextInputCode from '!!raw-loader!@site/src/ui/input/components/entityTitleDoubleTextInputCode.js'
import textAreaCode from '!!raw-loader!@site/src/ui/input/components/textAreaCode.js'
## Text Input
Allows users to enter and edit text.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/TextInput']}
componentCode={textInputCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td>string</td>
<td>Optional name for additional styling</td>
<td></td>
</tr>
<tr>
<td>label</td>
<td>string</td>
<td>Represents the label for the input</td>
<td></td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The function called when the input value changes</td>
<td></td>
</tr>
<tr>
<td>fullWidth</td>
<td>boolean</td>
<td>Indicates whether the input should take up 100% of the width</td>
<td></td>
</tr>
<tr>
<td>disableHotkeys</td>
<td>boolean</td>
<td>Indicates whether hotkeys are enabled for the input</td>
<td>`false`</td>
</tr>
<tr>
<td>error</td>
<td>string</td>
<td>Represents the error message to be displayed. When provided, it also adds an icon error on the right side of the input</td>
<td></td>
</tr>
<tr>
<td>onKeyDown</td>
<td>function</td>
<td>Called when a key is pressed down while the input field is focused. Receives a `React.KeyboardEvent` as an argument</td>
<td></td>
</tr>
<tr>
<td>RightIcon</td>
<td>IconComponent</td>
<td>An optional icon component displayed on the right side of the input</td>
<td></td>
</tr>
</tbody>
</table>
The component also accepts other HTML input element props.
</TabItem>
</Tabs>
## Autosize Text Input
Text input component that automatically adjusts its height based on the content.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/AutosizeTextInput']}
componentCode={autosizeTextInputCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>onValidate</td>
<td>function</td>
<td>The callback function you want to trigger when the user validates the input</td>
<td></td>
</tr>
<tr>
<td>minRows</td>
<td>number</td>
<td>The minimum number of rows for the text area</td>
<td>1</td>
</tr>
<tr>
<td>placeholder</td>
<td>string</td>
<td>The placeholder text you want to display when the text area is empty</td>
<td></td>
</tr>
<tr>
<td>onFocus</td>
<td>function</td>
<td>The callback function you want to trigger when the text area gains focus</td>
<td></td>
</tr>
<tr>
<td>variant</td>
<td>string</td>
<td>The variant of the input. Options include: `default`, `icon`, and `button`</td>
<td>default</td>
</tr>
<tr>
<td>buttonTitle</td>
<td>string</td>
<td>The title for the button (only applicable for the button variant)</td>
<td></td>
</tr>
<tr>
<td>value</td>
<td>string</td>
<td>The initial value for the text area</td>
<td>Empty string</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Entity Title Double Text Input
Displays a pair of text inputs side by side, allowing the user to edit two related values simultaneously.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/EntityTitleDoubleTextInput']}
componentCode={entityTitleDoubleTextInputCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>firstValue</td>
<td>string</td>
<td>The value for the first text input</td>
</tr>
<tr>
<td>secondValue</td>
<td>string</td>
<td>The value for the second text input</td>
</tr>
<tr>
<td>firstValuePlaceholder</td>
<td>string</td>
<td>Placeholder text for the first text input, displayed when the input is empty</td>
</tr>
<tr>
<td>secondValuePlaceholder</td>
<td>string</td>
<td>Placeholder text for the second text input, displayed when the input is empty</td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>The callback function you want to trigger when the text input changes</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>
## Text Area
Allows you to create multi-line text inputs.
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/TextArea']}
componentCode={textAreaCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>disabled</td>
<td>boolean</td>
<td>Indicates whether the text area is disabled</td>
<td></td>
</tr>
<tr>
<td>minRows</td>
<td>number</td>
<td>Minimum number of visible rows for the text area. </td>
<td>1</td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>Callback function triggered when the text area content changes</td>
<td></td>
</tr>
<tr>
<td>placeholder</td>
<td>string</td>
<td>Placeholder text displayed when the text area is empty</td>
<td></td>
</tr>
<tr>
<td>value</td>
<td>string</td>
<td>The current value of the text area</td>
<td>Empty string</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,71 @@
---
title: Toggle
sidebar_position: 10
sidebar_custom_props:
icon: TbToggleRight
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { SandpackEditor} from '@site/src/ui/SandpackEditor'
import toggleCode from '!!raw-loader!@site/src/ui/input/components/toggleCode.js'
<Tabs>
<TabItem value="usage" label="Usage" default>
<SandpackEditor
availableComponentPaths={['@/ui/input/components/Toggle']}
componentCode={toggleCode}
/>
</TabItem>
<TabItem value="props" label="Props">
<table>
<thead>
<tr>
<th>Props</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>value</td>
<td>boolean</td>
<td>The current state of the toggle</td>
<td>`false`</td>
</tr>
<tr>
<td>onChange</td>
<td>function</td>
<td>Callback function triggered when the toggle state changes</td>
<td></td>
</tr>
<tr>
<td>color</td>
<td>string</td>
<td>Color of the toggle when it's in the "on" state. If not provided, it uses the theme's blue color</td>
<td></td>
</tr>
<tr>
<td>toggleSize</td>
<td>string</td>
<td>Size of the toggle, affecting both height and weight. Has two options: `small` and `medium`</td>
<td>medium</td>
</tr>
</tbody>
</table>
</TabItem>
</Tabs>

View File

@ -0,0 +1,8 @@
---
title: UI Components
sidebar_position: 0
displayed_sidebar: uiDocsSidebar
sidebar_custom_props:
isSidebarRoot: true
icon: TbLayoutGrid
---