npm package: @mehmetyoldas/chd-auto-ui-react
Description: CHD Framework için metadata tabanlı dinamik React form ve grid bileşenleri.
Author: Mehmet Yoldaş
Latest version: 1.0.5

# CHD Auto-UI React

🚀 **Enterprise-Ready, Metadata-Driven React Forms & Grids for the CHD Framework**

[![npm version](https://badge.fury.io/js/@mehmetyoldas%2Fchd-auto-ui-react.svg)](https://www.npmjs.com/package/@mehmetyoldas/chd-auto-ui-react)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

---

## Why CHD Auto-UI React? (A Holistic, Real-World Approach)

CHD Auto-UI React, when used together with the **Chd.AutoUI NuGet** package (C#), revolutionizes enterprise UI development. All forms, grids, and validation rules are defined once in your C# DTOs using attributes. The backend automatically generates JSON metadata, and the React frontend instantly renders dynamic, consistent, and secure UIs from this metadata.

### Traditional vs. Metadata-Driven UI (A Practical Example)

**Without CHD Auto-UI:**
- You manually code every form field, validation, and grid column in React.
- You duplicate validation logic in both backend and frontend.
- UI changes require code changes in multiple places.

**With CHD Auto-UI:**
- You define your entity and UI rules once in C#:

```csharp
[AutoCRUD(Title = "Products", Icon = "📦")]
public class ProductDto
{
    [GridColumn(Order = 1, Width = 80)]
    [FormField(ReadOnly = true)]
    public int Id { get; set; }

    [GridColumn(Order = 2, Width = 200)]
    [FormField(Label = "Product Name", Type = FieldType.Text, Required = true, MaxLength = 100, Order = 1)]
    public string Name { get; set; } = string.Empty;

    [GridColumn(Order = 3, Width = 150, Format = "currency")]
    [FormField(Label = "Price", Type = FieldType.Number, Required = true, Order = 2)]
    public decimal Price { get; set; }

    [FormField(Label = "Status", Type = FieldType.Radio, Options = new[] { "Active", "Inactive" }, Order = 3)]
    public string Status { get; set; } = "Active";

    [FormField(Label = "Category", Type = FieldType.Dropdown, RelatedEntity = "categories", Order = 4)]
    public int? CategoryId { get; set; }
}
```

- Your API exposes `/api/products/metadata` (auto-generated by Chd.AutoUI).
- In React, you simply use:

```tsx
<DynamicForm endpoint="products" />
<DynamicGrid endpoint="products" />
```

- **Result:**
  - All fields, validation, dropdowns, and grid columns are generated automatically.
  - Any change in the C# DTO is instantly reflected in the UI—no double maintenance.
  - Validation, required fields, and even options are always in sync.

#### Code Comparison: Without vs. With AutoUI

**Without AutoUI (Classic React Example):**
```tsx
// ...hundreds of lines for form fields, validation, role checks, grid columns, etc.
<input type="text" value={name} onChange={...} required maxLength={100} />
{!user.roles.includes('Admin') ? null : <button onClick={deleteProduct}>Delete</button>}
// ...manual validation, manual API calls, manual error handling, manual role-based UI...
```

**With AutoUI:**
```tsx
<DynamicForm endpoint="products" />
<DynamicGrid endpoint="products" />
```

**Benefit:**
- Save hundreds of lines of code per entity.
- Eliminate duplication and human error.
- Instantly reflect backend changes in the UI.
- Role-based UI and validation are always in sync with backend rules.

---

## 🧩 Field Types: C# Attribute vs. React Usage

For each field type, simply define the attribute in your C# DTO. The React UI is generated automatically—no manual field code needed!

### Text Field
**C# Attribute:**
```csharp
[FormField(Label = "Name", Type = FieldType.Text, Required = true, MaxLength = 100)]
public string Name { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<input type="text" value={name} onChange={...} required maxLength={100} />
```

### TextArea
**C# Attribute:**
```csharp
[FormField(Label = "Description", Type = FieldType.TextArea, Rows = 4, MaxLength = 500)]
public string Description { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<textarea value={description} onChange={...} rows={4} maxLength={500} />
```

### Number Field
**C# Attribute:**
```csharp
[FormField(Label = "Price", Type = FieldType.Number, Required = true, Min = 0, Max = 10000, Step = 0.01)]
public decimal Price { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<input type="number" value={price} onChange={...} min={0} max={10000} step={0.01} />
```

### Date & DateTime Picker
**C# Attribute:**
```csharp
[FormField(Label = "Expiry Date", Type = FieldType.Date)]
public DateTime ExpiryDate { get; set; }

[FormField(Label = "Event Time", Type = FieldType.DateTime)]
public DateTime EventTime { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<input type="date" value={expiryDate} onChange={...} />
<input type="datetime-local" value={eventTime} onChange={...} />
```

### Checkbox
**C# Attribute:**
```csharp
[FormField(Label = "Is Active", Type = FieldType.Checkbox, DefaultValue = true)]
public bool IsActive { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<input type="checkbox" checked={isActive} onChange={...} />
```

### Radio Button
**C# Attribute:**
```csharp
[FormField(Label = "Status", Type = FieldType.Radio, Options = new[] { "Active", "Inactive" })]
public string Status { get; set; } = "Active";
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<div>
  <input type="radio" value="active" checked={status === 'active'} onChange={...} /> Active
  <input type="radio" value="inactive" checked={status === 'inactive'} onChange={...} /> Inactive
</div>
```

### Dropdown / ComboBox (Searchable)
**C# Attribute:**
```csharp
[FormField(Label = "Category", Type = FieldType.Dropdown, RelatedEntity = "categories")]
public int? CategoryId { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<select value={categoryId} onChange={...}>
  {categories.map(c => <option value={c.id}>{c.name}</option>)}
</select>
```

### MultiSelect (with Search & Chips)
**C# Attribute:**
```csharp
[FormField(Label = "Tags", Type = FieldType.MultiSelect, Options = new[] { "Organic", "Vegan" })]
public string Tags { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<ComboMultiSelect options={...} value={tags} onChange={...} />
```

### Autocomplete (Remote Data)
**C# Attribute:**
```csharp
[FormField(Label = "Supplier", Type = FieldType.Autocomplete, RemoteSource = "/api/suppliers/search")]
public int SupplierId { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<input type="text" value={supplierName} onChange={...} />
```

### TreeSelect (Hierarchical Selection)
**C# Attribute:**
```csharp
[FormField(Label = "Category", Type = FieldType.TreeSelect, TreeEntity = "categories")]
public int CategoryId { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<TreeSelect value={categoryId} onChange={...} treeData={categoriesTree} />
```

### File Upload
**C# Attribute:**
```csharp
[FormField(Label = "Product Image", Type = FieldType.File, Accept = "image/*")]
public string ImageUrl { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<input type="file" accept="image/*" onChange={...} />
```

### Rich Text Editor
**C# Attribute:**
```csharp
[FormField(Label = "Long Description", Type = FieldType.RichTextEditor, EditorConfig = "basic")]
public string LongDescription { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<RichTextEditor value={longDescription} onChange={...} config="basic" />
```

### Color Picker
**C# Attribute:**
```csharp
[FormField(Label = "Color", Type = FieldType.ColorPicker, DefaultValue = "#ff0000")]
public string ColorHex { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<ColorPicker color={colorHex} onChange={...} />
```

### Date Range Picker
**C# Attribute:**
```csharp
[FormField(Label = "Date Range", Type = FieldType.DateRange)]
public (DateTime Start, DateTime End) DateRange { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<DateRangePicker startDate={dateRange.Start} endDate={dateRange.End} onChange={...} />
```

### Stepper / Wizard Form
**C# Attribute:**
```csharp
[FormField(Label = "Steps", Type = FieldType.Stepper, Steps = new[] { "Basic Info", "Details", "Review" })]
public int Step { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<StepWizard initialStep={0} onStepChange={...}>
  <Step>...</Step>
  <Step>...</Step>
  <Step>...</Step>
</StepWizard>
```

### Tag Input
**C# Attribute:**
```csharp
[FormField(Label = "Tags", Type = FieldType.TagInput, Options = new[] { "Organic", "Vegan" })]
public string Tags { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<TagInput value={tags} onChange={...} suggestions={['Organic', 'Vegan']} />
```

### Image Preview
**C# Attribute:**
```csharp
[FormField(Label = "Preview", Type = FieldType.ImagePreview, ImageUrl = "{ImageUrl}")]
public string ImageUrl { get; set; }
```
**React Usage:**
```tsx
<DynamicForm endpoint="products" />
```
**Without AutoUI (for comparison):**
```tsx
<img src={imageUrl} alt="Product Image" />
```

### Custom Field Types
- **Use for:** Any custom UI/UX need
- **Features:** Plug in your own React component
```tsx
// Register a custom renderer
import { setCustomRenderer } from '@mehmetyoldas/chd-auto-ui-react';
setCustomRenderer('mycustom', (field, value, onChange) => <MyCustomComponent ... />);
```

---

## 🚀 Quick Start

```tsx
import React from 'react';
import { DynamicForm, DynamicGrid, setApiBase } from '@mehmetyoldas/chd-auto-ui-react';

setApiBase('https://localhost:5218/api');

function App() {
  return (
    <div>
      <h1>Product Management</h1>
      <DynamicGrid endpoint="products" />
      <DynamicForm endpoint="products" />
    </div>
  );
}
```

---

## 🌐 API Integration & Metadata

- **API Endpoints:**
  - `GET /api/{endpoint}` – List items
  - `GET /api/{endpoint}/{id}` – Get item
  - `POST /api/{endpoint}` – Create
  - `PUT /api/{endpoint}/{id}` – Update
  - `DELETE /api/{endpoint}/{id}` – Delete
  - `GET /api/{endpoint}/metadata` – Get metadata (auto-generated by Chd.AutoUI)
- **Metadata:**
  - Generated from C# DTOs with Chd.AutoUI attributes.
  - Includes field types, validation, options, and permissions.

---

## 🎨 Customization & Extensibility

- **Styling:** Use `className` and `style` props or override CSS.
- **Custom Renderers:** Register custom field types for advanced UI needs.
- **Event Hooks:** `onSave`, `onCancel`, `onEdit`, `onDelete`, etc.
- **Localization:** All labels and messages can be localized via metadata.

---

## 🧪 Testing & Best Practices

- **Unit Testing:** All components are testable with Jest/React Testing Library.
- **Validation:** Use metadata for required fields, min/max, regex, etc.
- **Accessibility:** All controls are keyboard accessible and ARIA-compliant.
- **Performance:** Async loading, virtualization for large lists, and optimized rendering.

---

## 📚 Example: Complete CRUD App

```tsx
import React, { useState } from 'react';
import { DynamicForm, DynamicGrid, setApiBase } from '@mehmetyoldas/chd-auto-ui-react';

setApiBase('https://api.example.com');

function App() {
  const [showForm, setShowForm] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);

  return (
    <div className="app">
      <h1>Product Management</h1>
      {!showForm ? (
        <DynamicGrid 
          endpoint="products"
          onAdd={() => setShowForm(true)}
          onEdit={(id) => { setEditingId(id); setShowForm(true); }}
          onDelete={async (id) => { /* handle delete */ }}
        />
      ) : (
        <DynamicForm 
          endpoint="products"
          itemId={editingId}
          onSave={() => { setShowForm(false); setEditingId(null); }}
          onCancel={() => { setShowForm(false); setEditingId(null); }}
        />
      )}
    </div>
  );
}
```

---

## 🔗 Related Packages
- [Chd.AutoUI (NuGet)](https://www.nuget.org/packages/Chd.AutoUI) – C# metadata attributes
- [Chd.AutoUI.EF (NuGet)](https://www.nuget.org/packages/Chd.AutoUI.EF) – Entity Framework integration

---

## 📝 License
MIT License – see LICENSE file for details

---

## 🤝 Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

---

## 💡 Why CHD Auto-UI React?

CHD Auto-UI React is designed for rapid, maintainable, and scalable enterprise UI development. By leveraging metadata-driven forms and grids, you can:
- Eliminate repetitive boilerplate code
- Ensure consistency across your application
- Easily adapt to changing business requirements
- Empower both backend and frontend teams to collaborate efficiently

**Accelerate your development with CHD Auto-UI React!**