@app-studio/web 0.9.17 → 0.9.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AuthGuard/index.d.ts +1 -1
- package/dist/utils/request.d.ts +2 -2
- package/dist/web.cjs.development.js +41 -46
- package/dist/web.cjs.development.js.map +1 -1
- package/dist/web.cjs.production.min.js +1 -1
- package/dist/web.cjs.production.min.js.map +1 -1
- package/dist/web.esm.js +43 -48
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +45 -45
- package/dist/web.umd.development.js.map +1 -1
- package/dist/web.umd.production.min.js +1 -1
- package/dist/web.umd.production.min.js.map +1 -1
- package/docs/README.md +52 -0
- package/docs/adk-components.md +316 -0
- package/docs/adk-quick-start.md +294 -0
- package/docs/api-integration.md +801 -0
- package/docs/api-reference/README.md +103 -0
- package/docs/api-reference/data-display/flow.md +220 -0
- package/docs/api-reference/data-display/tree.md +210 -0
- package/docs/api-reference/form/chat-input.md +210 -0
- package/docs/api-reference/utility/button.md +145 -0
- package/docs/api-reference/utility/title.md +301 -0
- package/docs/app-studio.md +302 -0
- package/docs/component-development/guide.md +546 -0
- package/docs/contributing/documentation.md +153 -0
- package/docs/conventions.md +536 -0
- package/docs/design-system/theming.md +299 -0
- package/docs/documentation-system.md +143 -0
- package/docs/getting-started/component-usage.md +211 -0
- package/docs/getting-started/introduction.md +114 -0
- package/docs/guide.md +550 -0
- package/docs/integration-guide.md +449 -0
- package/docs/tutorials/README.md +51 -0
- package/docs/tutorials/basic/creating-a-simple-form.md +566 -0
- package/package.json +3 -2
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
# Coding Conventions
|
|
2
|
+
|
|
3
|
+
This document outlines the coding conventions and standards used in the App Studio Web Component Library. Following these conventions ensures consistency across the codebase and makes it easier for developers to understand, maintain, and contribute to the project.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [File Structure Conventions](#file-structure-conventions)
|
|
8
|
+
2. [Naming Conventions](#naming-conventions)
|
|
9
|
+
3. [TypeScript Conventions](#typescript-conventions)
|
|
10
|
+
4. [React Conventions](#react-conventions)
|
|
11
|
+
5. [Styling Conventions](#styling-conventions)
|
|
12
|
+
6. [Component API Conventions](#component-api-conventions)
|
|
13
|
+
7. [Documentation Conventions](#documentation-conventions)
|
|
14
|
+
8. [Testing Conventions](#testing-conventions)
|
|
15
|
+
9. [Git Conventions](#git-conventions)
|
|
16
|
+
|
|
17
|
+
## File Structure Conventions
|
|
18
|
+
|
|
19
|
+
### Component Structure
|
|
20
|
+
|
|
21
|
+
Components follow a consistent file structure:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
ComponentName/
|
|
25
|
+
├── ComponentName.tsx # Main component file (exports public API)
|
|
26
|
+
├── ComponentName/ # Inner folder for core files
|
|
27
|
+
│ ├── ComponentName.props.ts # Props interface definitions
|
|
28
|
+
│ ├── ComponentName.state.ts # Custom state hook
|
|
29
|
+
│ ├── ComponentName.view.tsx # Presentational component
|
|
30
|
+
│ ├── ComponentName.style.ts # Style constants and theme mappings
|
|
31
|
+
│ └── ComponentName.type.ts # TypeScript type definitions
|
|
32
|
+
└── examples/ # Usage examples
|
|
33
|
+
├── default.tsx # Default usage example
|
|
34
|
+
├── variant.tsx # Variant-specific example
|
|
35
|
+
├── size.tsx # Size-specific example
|
|
36
|
+
└── index.ts # Exports all examples
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Import Order
|
|
40
|
+
|
|
41
|
+
Imports should be organized in the following order:
|
|
42
|
+
|
|
43
|
+
1. React and React-related imports
|
|
44
|
+
2. Third-party library imports
|
|
45
|
+
3. App-studio imports
|
|
46
|
+
4. Internal component imports
|
|
47
|
+
5. Type imports
|
|
48
|
+
6. Style imports
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// React and React-related imports
|
|
54
|
+
import React, { useState, useCallback } from 'react';
|
|
55
|
+
|
|
56
|
+
// Third-party library imports
|
|
57
|
+
import { useFormik } from 'formik';
|
|
58
|
+
import * as Yup from 'yup';
|
|
59
|
+
|
|
60
|
+
// App-studio imports
|
|
61
|
+
import { View, Horizontal, Vertical, useTheme } from 'app-studio';
|
|
62
|
+
|
|
63
|
+
// Internal component imports
|
|
64
|
+
import { Text } from '../../Text/Text';
|
|
65
|
+
import { Button } from '../../Button/Button';
|
|
66
|
+
|
|
67
|
+
// Type imports
|
|
68
|
+
import { TextFieldProps } from './TextField.props';
|
|
69
|
+
|
|
70
|
+
// Style imports
|
|
71
|
+
import { TextFieldSizes, TextFieldVariants } from './TextField.style';
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Naming Conventions
|
|
75
|
+
|
|
76
|
+
### Component Names
|
|
77
|
+
|
|
78
|
+
- Use PascalCase for component names: `Button`, `TextField`, `NavigationMenu`
|
|
79
|
+
- Use descriptive names that clearly indicate the component's purpose
|
|
80
|
+
- Avoid abbreviations unless they are widely understood
|
|
81
|
+
|
|
82
|
+
### File Names
|
|
83
|
+
|
|
84
|
+
- Use PascalCase for component files: `Button.tsx`, `TextField.props.ts`
|
|
85
|
+
- Use camelCase for utility files: `generateId.ts`, `useMediaQuery.ts`
|
|
86
|
+
- Use kebab-case for documentation files: `component-development.md`
|
|
87
|
+
|
|
88
|
+
### Variable and Function Names
|
|
89
|
+
|
|
90
|
+
- Use camelCase for variables and functions: `isHovered`, `handleClick`
|
|
91
|
+
- Use descriptive names that clearly indicate the variable or function's purpose
|
|
92
|
+
- Prefix boolean variables with `is`, `has`, or `should`: `isDisabled`, `hasError`
|
|
93
|
+
- Prefix event handlers with `handle` or `on`: `handleClick`, `onSubmit`
|
|
94
|
+
|
|
95
|
+
### Type and Interface Names
|
|
96
|
+
|
|
97
|
+
- Use PascalCase for types and interfaces: `ButtonProps`, `Size`, `Variant`
|
|
98
|
+
- Suffix props interfaces with `Props`: `ButtonProps`, `TextFieldProps`
|
|
99
|
+
- Suffix style interfaces with `Styles`: `ButtonStyles`, `TextFieldStyles`
|
|
100
|
+
- Suffix context types with `Context`: `ThemeContext`, `FormContext`
|
|
101
|
+
|
|
102
|
+
### Enum Names
|
|
103
|
+
|
|
104
|
+
- Use PascalCase for enum names: `ButtonVariant`, `TextFieldSize`
|
|
105
|
+
- Use singular form for enum names: `Size` instead of `Sizes`
|
|
106
|
+
- Use PascalCase for enum values if they are used as types: `Size.Small`, `Variant.Primary`
|
|
107
|
+
- Use UPPER_SNAKE_CASE for enum values if they are constants: `HTTP_METHOD.GET`, `ERROR_CODE.NOT_FOUND`
|
|
108
|
+
|
|
109
|
+
## TypeScript Conventions
|
|
110
|
+
|
|
111
|
+
### Type Definitions
|
|
112
|
+
|
|
113
|
+
- Define types in `.type.ts` files
|
|
114
|
+
- Export types for external use
|
|
115
|
+
- Use TypeScript's built-in utility types when appropriate: `Partial<T>`, `Omit<T, K>`, `Pick<T, K>`
|
|
116
|
+
- Use union types for finite sets of values: `type Size = 'sm' | 'md' | 'lg'`
|
|
117
|
+
- Use interfaces for object shapes: `interface ButtonProps { ... }`
|
|
118
|
+
|
|
119
|
+
### Type Annotations
|
|
120
|
+
|
|
121
|
+
- Add type annotations for function parameters and return types
|
|
122
|
+
- Use explicit type annotations for complex types
|
|
123
|
+
- Use type inference for simple types
|
|
124
|
+
- Use `React.FC<Props>` for functional components
|
|
125
|
+
|
|
126
|
+
### Generics
|
|
127
|
+
|
|
128
|
+
- Use generics for reusable components and utilities
|
|
129
|
+
- Use descriptive names for generic type parameters: `TValue`, `TItem` instead of `T`, `U`
|
|
130
|
+
- Constrain generic types when possible: `<T extends HTMLElement>`
|
|
131
|
+
|
|
132
|
+
### Enums vs Union Types
|
|
133
|
+
|
|
134
|
+
- Use union types for simple sets of string literals: `type Size = 'sm' | 'md' | 'lg'`
|
|
135
|
+
- Use enums for sets of related values that may change or need to be referenced programmatically
|
|
136
|
+
|
|
137
|
+
## React Conventions
|
|
138
|
+
|
|
139
|
+
### Functional Components
|
|
140
|
+
|
|
141
|
+
- Use functional components with hooks instead of class components
|
|
142
|
+
- Define components using arrow functions
|
|
143
|
+
- Use the `React.FC<Props>` type for components
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import React from 'react';
|
|
149
|
+
import { ButtonProps } from './Button.props';
|
|
150
|
+
|
|
151
|
+
const ButtonComponent: React.FC<ButtonProps> = (props) => {
|
|
152
|
+
// Component implementation
|
|
153
|
+
return <div>{/* JSX */}</div>;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const Button = ButtonComponent;
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Hooks
|
|
160
|
+
|
|
161
|
+
- Create custom hooks for reusable logic
|
|
162
|
+
- Name custom hooks with the `use` prefix: `useButtonState`, `useFormField`
|
|
163
|
+
- Keep hooks focused on a single concern
|
|
164
|
+
- Extract complex logic into custom hooks
|
|
165
|
+
|
|
166
|
+
Example:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { useState, useCallback } from 'react';
|
|
170
|
+
|
|
171
|
+
export const useButtonState = () => {
|
|
172
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
173
|
+
|
|
174
|
+
const handleMouseEnter = useCallback(() => {
|
|
175
|
+
setIsHovered(true);
|
|
176
|
+
}, []);
|
|
177
|
+
|
|
178
|
+
const handleMouseLeave = useCallback(() => {
|
|
179
|
+
setIsHovered(false);
|
|
180
|
+
}, []);
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
isHovered,
|
|
184
|
+
handleMouseEnter,
|
|
185
|
+
handleMouseLeave,
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Props
|
|
191
|
+
|
|
192
|
+
- Define props in a separate `.props.ts` file
|
|
193
|
+
- Use destructuring to access props
|
|
194
|
+
- Provide default values for optional props
|
|
195
|
+
- Document props with JSDoc comments
|
|
196
|
+
|
|
197
|
+
Example:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// Button.props.ts
|
|
201
|
+
export interface ButtonProps {
|
|
202
|
+
/**
|
|
203
|
+
* The visual style of the button
|
|
204
|
+
* @default 'filled'
|
|
205
|
+
*/
|
|
206
|
+
variant?: 'filled' | 'outline' | 'ghost' | 'link';
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The size of the button
|
|
210
|
+
* @default 'md'
|
|
211
|
+
*/
|
|
212
|
+
size?: 'sm' | 'md' | 'lg';
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Whether the button is disabled
|
|
216
|
+
* @default false
|
|
217
|
+
*/
|
|
218
|
+
isDisabled?: boolean;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The function to call when the button is clicked
|
|
222
|
+
*/
|
|
223
|
+
onClick?: () => void;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Button.view.tsx
|
|
227
|
+
const ButtonView: React.FC<ButtonProps> = ({
|
|
228
|
+
variant = 'filled',
|
|
229
|
+
size = 'md',
|
|
230
|
+
isDisabled = false,
|
|
231
|
+
onClick,
|
|
232
|
+
...props
|
|
233
|
+
}) => {
|
|
234
|
+
// Component implementation
|
|
235
|
+
};
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### JSX
|
|
239
|
+
|
|
240
|
+
- Use self-closing tags for components without children: `<Button />`
|
|
241
|
+
- Use explicit `children` prop for components with children
|
|
242
|
+
- Use fragments (`<>...</>`) to avoid unnecessary wrapper elements
|
|
243
|
+
- Use conditional rendering with ternary operators or logical AND (`&&`)
|
|
244
|
+
|
|
245
|
+
Example:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
const ButtonView: React.FC<ButtonProps> = ({ children, isDisabled, ...props }) => {
|
|
249
|
+
return (
|
|
250
|
+
<button disabled={isDisabled} {...props}>
|
|
251
|
+
{isDisabled ? (
|
|
252
|
+
<span className="disabled-text">{children}</span>
|
|
253
|
+
) : (
|
|
254
|
+
children
|
|
255
|
+
)}
|
|
256
|
+
</button>
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Styling Conventions
|
|
262
|
+
|
|
263
|
+
### App-Studio Layout Components
|
|
264
|
+
|
|
265
|
+
Use the layout components from `app-studio` for consistent layout:
|
|
266
|
+
- `View`: Base container component
|
|
267
|
+
- `Horizontal`: Horizontal flex container
|
|
268
|
+
- `Vertical`: Vertical flex container
|
|
269
|
+
- `Center`: Centered flex container
|
|
270
|
+
|
|
271
|
+
Example:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { View, Horizontal, Vertical, Center } from 'app-studio';
|
|
275
|
+
|
|
276
|
+
const CardView: React.FC<CardProps> = ({ title, content, footer }) => {
|
|
277
|
+
return (
|
|
278
|
+
<View padding={16} borderRadius={8} backgroundColor="white">
|
|
279
|
+
<Vertical gap={16}>
|
|
280
|
+
<Text fontWeight="bold">{title}</Text>
|
|
281
|
+
<View>{content}</View>
|
|
282
|
+
<Horizontal justifyContent="flex-end">{footer}</Horizontal>
|
|
283
|
+
</Vertical>
|
|
284
|
+
</View>
|
|
285
|
+
);
|
|
286
|
+
};
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Theme Integration
|
|
290
|
+
|
|
291
|
+
Use the theme system via `useTheme` hook:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
const { getColor, themeMode } = useTheme();
|
|
295
|
+
const colorValue = getColor('theme.primary', { themeMode });
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Style Constants
|
|
299
|
+
|
|
300
|
+
Define style constants in `.style.ts` files:
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
export const ButtonSizes = {
|
|
304
|
+
sm: { height: 30, fontSize: 14, padding: '0 12px' },
|
|
305
|
+
md: { height: 40, fontSize: 16, padding: '0 16px' },
|
|
306
|
+
lg: { height: 50, fontSize: 18, padding: '0 20px' },
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
export const ButtonShapes = {
|
|
310
|
+
sharp: { borderRadius: 0 },
|
|
311
|
+
rounded: { borderRadius: 4 },
|
|
312
|
+
pillShaped: { borderRadius: 9999 },
|
|
313
|
+
};
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Style Customization
|
|
317
|
+
|
|
318
|
+
Allow style customization through the `views` prop:
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
<View
|
|
322
|
+
{...defaultStyles}
|
|
323
|
+
{...views?.container}
|
|
324
|
+
{...props}
|
|
325
|
+
>
|
|
326
|
+
<Text {...views?.label}>{label}</Text>
|
|
327
|
+
</View>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Component API Conventions
|
|
331
|
+
|
|
332
|
+
### Prop Naming
|
|
333
|
+
|
|
334
|
+
- Use descriptive prop names that clearly indicate the prop's purpose
|
|
335
|
+
- Use boolean props with the `is` or `has` prefix: `isDisabled`, `hasError`
|
|
336
|
+
- Use consistent prop names across components: `size`, `variant`, `shape`
|
|
337
|
+
- Use `children` for component content
|
|
338
|
+
- Use `views` for style customization
|
|
339
|
+
|
|
340
|
+
### Prop Types
|
|
341
|
+
|
|
342
|
+
- Use union types for props with a finite set of values: `variant: 'filled' | 'outline' | 'ghost' | 'link'`
|
|
343
|
+
- Use `React.ReactNode` for content props: `children: React.ReactNode`
|
|
344
|
+
- Use function types for event handlers: `onClick: () => void`
|
|
345
|
+
- Use object types for complex props: `style: React.CSSProperties`
|
|
346
|
+
|
|
347
|
+
### Default Props
|
|
348
|
+
|
|
349
|
+
- Provide default values for optional props
|
|
350
|
+
- Document default values in JSDoc comments
|
|
351
|
+
- Set default values in the component function parameter destructuring
|
|
352
|
+
|
|
353
|
+
Example:
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
/**
|
|
357
|
+
* Button component for user interaction
|
|
358
|
+
*/
|
|
359
|
+
const ButtonView: React.FC<ButtonProps> = ({
|
|
360
|
+
variant = 'filled',
|
|
361
|
+
size = 'md',
|
|
362
|
+
shape = 'rounded',
|
|
363
|
+
isDisabled = false,
|
|
364
|
+
children,
|
|
365
|
+
...props
|
|
366
|
+
}) => {
|
|
367
|
+
// Component implementation
|
|
368
|
+
};
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Component Composition
|
|
372
|
+
|
|
373
|
+
- Use compound components for complex components
|
|
374
|
+
- Export sub-components as properties of the main component
|
|
375
|
+
- Use context for sharing state between compound components
|
|
376
|
+
|
|
377
|
+
Example:
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
// Card.tsx
|
|
381
|
+
export const Card = CardComponent as CardType;
|
|
382
|
+
|
|
383
|
+
// Assign the sub-components to the main component
|
|
384
|
+
Card.Header = CardHeader;
|
|
385
|
+
Card.Content = CardContent;
|
|
386
|
+
Card.Footer = CardFooter;
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Documentation Conventions
|
|
390
|
+
|
|
391
|
+
### JSDoc Comments
|
|
392
|
+
|
|
393
|
+
- Use JSDoc comments for props, functions, and types
|
|
394
|
+
- Include descriptions, default values, and examples
|
|
395
|
+
- Use `@param` for function parameters
|
|
396
|
+
- Use `@returns` for function return values
|
|
397
|
+
- Use `@example` for usage examples
|
|
398
|
+
|
|
399
|
+
Example:
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
/**
|
|
403
|
+
* Button component for user interaction
|
|
404
|
+
* @example
|
|
405
|
+
* ```tsx
|
|
406
|
+
* <Button variant="filled" size="md" onClick={() => alert('Clicked!')}>
|
|
407
|
+
* Click Me
|
|
408
|
+
* </Button>
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
export interface ButtonProps {
|
|
412
|
+
/**
|
|
413
|
+
* The visual style of the button
|
|
414
|
+
* @default 'filled'
|
|
415
|
+
*/
|
|
416
|
+
variant?: 'filled' | 'outline' | 'ghost' | 'link';
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* The size of the button
|
|
420
|
+
* @default 'md'
|
|
421
|
+
*/
|
|
422
|
+
size?: 'sm' | 'md' | 'lg';
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Component Examples
|
|
427
|
+
|
|
428
|
+
- Create examples for each significant prop or feature
|
|
429
|
+
- Use descriptive names for example files
|
|
430
|
+
- Export examples from `examples/index.ts`
|
|
431
|
+
- Include a default example that shows basic usage
|
|
432
|
+
|
|
433
|
+
Example:
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
// examples/default.tsx
|
|
437
|
+
import React from 'react';
|
|
438
|
+
import { Button } from '../Button';
|
|
439
|
+
|
|
440
|
+
export const DefaultButton = () => (
|
|
441
|
+
<Button onClick={() => alert('Hello, World!')}>Default</Button>
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
// examples/variant.tsx
|
|
445
|
+
import React from 'react';
|
|
446
|
+
import { Button } from '../Button';
|
|
447
|
+
import { Horizontal } from 'app-studio';
|
|
448
|
+
|
|
449
|
+
export const VariantButtons = () => (
|
|
450
|
+
<Horizontal gap={10}>
|
|
451
|
+
<Button variant="filled">Filled</Button>
|
|
452
|
+
<Button variant="outline">Outline</Button>
|
|
453
|
+
<Button variant="ghost">Ghost</Button>
|
|
454
|
+
<Button variant="link">Link</Button>
|
|
455
|
+
</Horizontal>
|
|
456
|
+
);
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### MDX Documentation
|
|
460
|
+
|
|
461
|
+
- Use MDX for component documentation
|
|
462
|
+
- Include import examples, props tables, and usage examples
|
|
463
|
+
- Use live code examples where possible
|
|
464
|
+
- Document accessibility features and best practices
|
|
465
|
+
|
|
466
|
+
## Testing Conventions
|
|
467
|
+
|
|
468
|
+
### Test File Structure
|
|
469
|
+
|
|
470
|
+
- Place test files in the `__tests__` directory
|
|
471
|
+
- Name test files after the component or utility they test: `button.test.tsx`
|
|
472
|
+
- Group related tests using `describe` blocks
|
|
473
|
+
- Use descriptive test names that explain what is being tested
|
|
474
|
+
|
|
475
|
+
### Test Coverage
|
|
476
|
+
|
|
477
|
+
- Test component rendering
|
|
478
|
+
- Test component props and their effects
|
|
479
|
+
- Test component interactions
|
|
480
|
+
- Test component edge cases
|
|
481
|
+
- Test component accessibility
|
|
482
|
+
|
|
483
|
+
Example:
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
import React from 'react';
|
|
487
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
488
|
+
import { Button } from '../Button';
|
|
489
|
+
|
|
490
|
+
describe('Button', () => {
|
|
491
|
+
test('renders correctly', () => {
|
|
492
|
+
render(<Button>Click Me</Button>);
|
|
493
|
+
expect(screen.getByText('Click Me')).toBeInTheDocument();
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
test('calls onClick when clicked', () => {
|
|
497
|
+
const handleClick = jest.fn();
|
|
498
|
+
render(<Button onClick={handleClick}>Click Me</Button>);
|
|
499
|
+
fireEvent.click(screen.getByText('Click Me'));
|
|
500
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
test('is disabled when isDisabled is true', () => {
|
|
504
|
+
render(<Button isDisabled>Click Me</Button>);
|
|
505
|
+
expect(screen.getByText('Click Me')).toBeDisabled();
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
## Git Conventions
|
|
511
|
+
|
|
512
|
+
### Branch Naming
|
|
513
|
+
|
|
514
|
+
- Use feature branches for new features: `feature/button-component`
|
|
515
|
+
- Use bugfix branches for bug fixes: `bugfix/button-disabled-state`
|
|
516
|
+
- Use hotfix branches for urgent fixes: `hotfix/critical-button-bug`
|
|
517
|
+
- Use release branches for releases: `release/v1.0.0`
|
|
518
|
+
|
|
519
|
+
### Commit Messages
|
|
520
|
+
|
|
521
|
+
- Use conventional commit messages: `feat: add button component`
|
|
522
|
+
- Use present tense: `add` instead of `added`
|
|
523
|
+
- Keep commit messages concise and descriptive
|
|
524
|
+
- Reference issues in commit messages: `fix: button disabled state (#123)`
|
|
525
|
+
|
|
526
|
+
### Pull Requests
|
|
527
|
+
|
|
528
|
+
- Use descriptive titles for pull requests
|
|
529
|
+
- Include a description of the changes
|
|
530
|
+
- Reference related issues
|
|
531
|
+
- Include screenshots or videos for visual changes
|
|
532
|
+
- Ensure all tests pass before merging
|
|
533
|
+
|
|
534
|
+
## Conclusion
|
|
535
|
+
|
|
536
|
+
Following these conventions ensures consistency across the codebase and makes it easier for developers to understand, maintain, and contribute to the project. If you have any questions or suggestions for improving these conventions, please open an issue or pull request.
|