Patterns: Components
Functional component structure, PropTypes, import ordering, state-management layers, forms, and file/folder naming. Load via the
patterns-componentscontext group.
Structure
All components are functional with hooks. No class components (one legacy HOC exception in Charts/autoHeight.js).
Props are typed with PropTypes (bottom of file):
MyComponent.propTypes = {
data: PropTypes.object,
isLoading: PropTypes.bool,
onSubmit: PropTypes.func,
};
Default props use destructuring defaults (no .defaultProps):
const MyComponent = ({ avatarSize = 24, showName = true }) => { ... };
Import Ordering
Consistent 3-section + local constants pattern:
// Core imports
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
// Component imports
import { Button, Form, Input, Typography } from 'antd';
import MyComponent from '../components/UI/MyComponent';
// Misc imports
import { useUserPermissions } from '../utils/hooks/useUserPermissions';
import { PERMISSIONS_ORG } from '../constants/main';
import { useGetBotsQuery } from '../store/bots/botsApi';
// Constant declarations
const { Text, Title } = Typography;
const SOME_LOCAL_CONSTANT = 'value';
All imports are relative. No path aliases exist. All imports at the top of the file; never inside functions or conditionals.
State Management Layers
- RTK Query (server state): API files inject endpoints into a single
apiSlice. Standard for all data fetching. - Redux slices (client/socket state):
authSlice,globalSlice,liveChatSlice,botsSlice, etc. Used for UI state and WebSocket-driven data. - React Context (component subtree state): Used sparingly for tight component trees (
LiveChatContext,GraphContext). useState(component-local state): Universal.useReduceris not used anywhere.
RTK Query patterns:
useGetXQuery()for auto-fetchinguseLazyGetXQuery()for imperative fetchinguseXMutation()for mutationsgetCurrentQueryState()helper to read cached data without re-fetching- Cache invalidation via tag-based system (
API_TAGSinconstants/api.js)
Form Handling
Ant Design Form exclusively. No React Hook Form or Formik.
const [form] = Form.useForm();
<Form form={form} layout="vertical" onFinish={handleSubmit} initialValues={initialValues}>
<Form.Item name="email" rules={[{ required: true, type: 'email' }]}>
<Input />
</Form.Item>
</Form>
Server-side errors injected via form.setFields([{ name, errors }]).
Parent-controlled forms pass the form instance as a prop for external submit triggers.
File and Folder Naming
| Category | Convention | Examples |
|---|---|---|
| Component files | PascalCase.jsx | BotScreen.jsx, MessageNode.jsx, LiveChatMessenger.jsx |
| Icon files | PascalCase.js | HelviaIcon.js, LiveChatIcon.js |
| Utility directories | camelCase/index.js | utils/string/replaceUrlParams/index.js |
| Hook directories | camelCase/index.js | utils/hooks/useBotLanguage/index.js |
| Style files | lowercase.less | livechat.less, forms.less, layout.less |
| Constant files | camelCase.js | flowGraph.js, liveChat.js |
| Store features | camelCase dir, featureApi.js / featureSlice.js / featureActions.js / featureMessages.js | store/bots/botsApi.js |
| Test files | .test.js | Only in utils/is/ and utils/array/ |
No index.jsx component pattern. Each component is its own named file.