# @idds/react

React UI component library for INA Digital Design System.

This package provides a comprehensive set of React components built with TypeScript. All styles are managed centrally in `@idds/styles` package and are **not dependent on Tailwind CSS classes**. Components use pure CSS with BEM-like naming conventions.

## Installation

```bash
npm install @idds/react
```

## Peer Dependencies

```bash
npm install react@>=18.0.0 react-dom@>=18.0.0
```

## Quick Start

### 1. Import CSS

Import the styles in your application entry point:

```jsx
// src/main.jsx or src/index.jsx
import '@idds/react/style.css';
```

### 2. Import and Use Components

```jsx
import { Button, TextField } from '@idds/react';

function App() {
  return (
    <div>
      <Button variant="primary" size="md">
        Click me
      </Button>
      <TextField
        label="Email"
        placeholder="Enter your email"
        value={value}
        onChange={setValue}
      />
    </div>
  );
}
```

## Usage

### Import Individual Components

```jsx
import { Button, TextField, SelectDropdown, Modal } from '@idds/react';
```

### Import All Components

```jsx
import * as IDDS from '@idds/react';

// Use components
const { Button, TextField, SelectDropdown } = IDDS;
```

### Import Color Tokens (Optional - for Tailwind CSS integration)

If you want to use INA Digital color tokens with Tailwind CSS in your project:

#### Tailwind CSS v3

For Tailwind CSS v3, import the TypeScript token files:

```jsx
// tailwind.config.js
import iddsColorTokens from '@idds/react';
import bgnColorTokens from '@idds/react'; // Brand-specific tokens

export default {
  theme: {
    extend: {
      colors: {
        ...iddsColorTokens,
        ...bgnColorTokens,
      },
    },
  },
};
```

#### Tailwind CSS v4

For Tailwind CSS v4, import the CSS theme files directly in your main CSS file:

```css
/* src/index.css or your main CSS file */

/* Tailwind CSS v4 */
@import 'tailwindcss';

/* INA Digital color tokens */
@import '@idds/styles/tailwind/css/idds.css';
@import '@idds/styles/tailwind/css/bgn.css'; /* Optional: brand theme */
```

Or use minified versions for production:

```css
@import 'tailwindcss';
@import '@idds/styles/tailwind/css/idds.min.css';
@import '@idds/styles/tailwind/css/bgn.min.css';
```

Then you can use Tailwind utility classes with INA Digital colors:

```jsx
<div className="bg-blue-500 text-white p-4">
  <p className="text-guide-500">This text uses guide-500 color</p>
  <p className="text-neutral-500">This text uses neutral-500 color</p>
</div>
```

**Available brand theme files:**

- `@idds/styles/tailwind/css/idds.css` - Default theme
- `@idds/styles/tailwind/css/inagov.css` - INAGov brand
- `@idds/styles/tailwind/css/inaku.css` - INAKu brand
- `@idds/styles/tailwind/css/inapas.css` - INAPas brand
- `@idds/styles/tailwind/css/bgn.css` - BGN brand
- `@idds/styles/tailwind/css/bkn.css` - BKN brand
- `@idds/styles/tailwind/css/lan.css` - LAN brand
- `@idds/styles/tailwind/css/panrb.css` - panrb brand

## Available Components

### Form Components

- **TextField** - Text input with validation, clear button, and character count
- **TextArea** - Multi-line text input with autosize
- **PasswordInput** - Password input with show/hide toggle
- **SelectDropdown** - Dropdown select with search and multi-select support
- **Checkbox** - Checkbox input
- **RadioInput** - Radio button input
- **DatePicker** - Date picker with single, range, and multiple modes
- **TimePicker** - Time picker
- **YearPicker** - Year picker
- **MonthPicker** - Month picker
- **PhoneInput** - Phone number input with country selector
- **OneTimePassword** - OTP input component
- **FileUpload** - File upload with drag & drop and validation
- **SingleFileUpload** - Single file upload component
- **Toggle** - Toggle switch component

### Layout Components

- **Card** - Card container component
- **Accordion** - Collapsible accordion component
- **AccordionCard** - Accordion with card styling
- **AccordionGroup** - Group of accordions
- **Divider** - Horizontal or vertical divider
- **Stepper** - Step indicator component
- **Breadcrumb** - Breadcrumb navigation
- **TabHorizontal** - Horizontal tabs
- **TabVertical** - Vertical tabs

### Feedback Components

- **Alert** - Alert message component
- **Toast** - Toast notification (use with ToastProvider)
- **ToastProvider** - Provider for toast notifications
- **Modal** - Modal dialog component
- **Drawer** - Side drawer component
- **BottomSheet** - Bottom sheet component
- **Tooltip** - Tooltip component
- **Skeleton** - Loading skeleton component
- **Spinner** - Loading spinner component
- **ProgressBar** - Progress bar component
- **LinearProgressIndicator** - Linear progress indicator
- **TableProgressBar** - Progress bar for tables

### Data Display Components

- **Table** - Advanced table with sorting, pagination, and editing
- **FieldInputTable** - Table with inline input fields
- **MultipleChoiceGrid** - Grid for multiple choice questions
- **Avatar** - Avatar component
- **Badge** - Badge component
- **Chip** - Chip component
- **List** - List component with variants
- **ListItem** - List item component
- **ListItemAvatar** - List item with avatar
- **ListItemButton** - List item as button
- **ListItemIcon** - List item with icon
- **ListItemText** - List item text
- **ListSubheader** - List subheader

### Navigation Components

- **Button** - Button component with multiple variants
- **ButtonGroup** - Group of buttons
- **ActionDropdown** - Dropdown menu for actions
- **Dropdown** - General dropdown component
- **Pagination** - Pagination component
- **InputSearch** - Search input component

### Other Components

- **ThemeToggle** - Dark/light theme toggle
- **Collapse** - Collapsible content component

## Theme System

### Setting Brand Theme

The design system supports multiple brand themes. You can switch between them programmatically:

```jsx
import { setBrandTheme } from '@idds/react';

// Set brand theme
setBrandTheme('bgn'); // or 'inagov', 'inaku', 'inapas', 'bkn', 'lan', 'panrb'

// Use default theme
setBrandTheme('default');

// Remove brand theme (use default)
setBrandTheme(null);
```

### Available Brand Themes

- `'default'` - Default INA Digital theme
- `'inagov'` - INAGov brand theme
- `'inaku'` - INAKu brand theme
- `'inapas'` - INAPas brand theme
- `'bgn'` - BGN brand theme
- `'bkn'` - BKN brand theme
- `'lan'` - LAN brand theme
- `'panrb'` - panrb brand theme

### Custom Theme

You can also set a custom theme:

```jsx
import { setCustomTheme } from '@idds/react';

setCustomTheme({
  name: 'custom',
  colors: {
    primary500: '#0968f6',
    primary600: '#0754c4',
    // ... other color tokens
  },
});
```

### Theme Utilities

```jsx
import {
  getCurrentTheme,
  getAvailableBrands,
  resetTheme,
  isValidBrand,
} from '@idds/react';

// Get current active theme
const currentTheme = getCurrentTheme();

// Get available brand names
const brands = getAvailableBrands();

// Reset to default theme
resetTheme();

// Validate brand name
if (isValidBrand('bgn')) {
  setBrandTheme('bgn');
}
```

## Utilities

### Form Utilities

```jsx
import { useForm, FormProvider, FormField } from '@idds/react';

// Form handling with validation
const { handleSubmit, register, errors } = useForm();
```

### Confirmation Dialog

```jsx
import { ConfirmationProvider, useConfirmation } from '@idds/react';

// Wrap your app
<ConfirmationProvider>
  <App />
</ConfirmationProvider>;

// Use in components
const confirm = useConfirmation();

const handleDelete = async () => {
  const result = await confirm({
    title: 'Delete Item',
    message: 'Are you sure you want to delete this item?',
  });

  if (result) {
    // User confirmed
  }
};
```

### Toast Notifications

```jsx
import { ToastProvider, useToast } from '@idds/react';

// Wrap your app
<ToastProvider>
  <App />
</ToastProvider>;

// Use in components
const toast = useToast();

toast.success('Operation completed successfully!');
toast.error('An error occurred');
toast.info('Information message');
toast.warning('Warning message');
```

### Security Utilities

```jsx
import {
  sanitizeInput,
  validateInput,
  encodeHtmlEntities,
  decodeHtmlEntities,
} from '@idds/react';

// Sanitize user input
const sanitized = sanitizeInput(userInput);

// Validate input for XSS
const validation = validateInput(userInput);
if (!validation.isValid) {
  console.warn('Security threat detected:', validation.threats);
}
```

### File Validation

```jsx
import { validateFile, validateMagicNumber, formatFileSize } from '@idds/react';

// Validate file
const result = validateFile(file, {
  allowedTypes: 'image/*',
  maxSize: 5 * 1024 * 1024, // 5MB
});

// Validate magic number (file signature)
const magicResult = await validateMagicNumber(file, 'image/png');

// Format file size
const formatted = formatFileSize(1024 * 1024); // "1 MB"
```

### Formatting Utilities

```jsx
import {
  formattingThousand,
  onlyAlphanumeric,
  onlyNumericValue,
  onlyDecimalNumber,
} from '@idds/react';

formattingThousand(1000000); // "1,000,000"
onlyAlphanumeric('abc123!@#'); // "abc123"
onlyNumericValue('123abc'); // "123"
onlyDecimalNumber('123.45'); // "123.45"
```

## Component Examples

### TextField

```jsx
import { TextField } from '@idds/react';

<TextField
  label="Email"
  placeholder="Enter your email"
  value={email}
  onChange={setEmail}
  type="email"
  required
  showClearButton
  maxLength={100}
  showCharCount
/>;
```

### Button

```jsx
import { Button } from '@idds/react';

<Button variant="primary" size="md" onClick={handleClick}>
  Submit
</Button>;
```

### SelectDropdown

```jsx
import { SelectDropdown } from '@idds/react';

const options = [
  { value: '1', label: 'Option 1' },
  { value: '2', label: 'Option 2' },
];

<SelectDropdown
  label="Select Option"
  options={options}
  value={selected}
  onChange={setSelected}
  searchable
  clearable
/>;
```

### DatePicker

```jsx
import { DatePicker } from '@idds/react';

<DatePicker
  label="Select Date"
  value={date}
  onChange={setDate}
  mode="single"
  dateFormat="DD/MM/YYYY"
  showIcon
  showClearButton
/>;
```

### Table

```jsx
import { Table } from '@idds/react';

const columns = [
  { key: 'name', label: 'Name' },
  { key: 'email', label: 'Email' },
];

const data = [
  { id: 1, name: 'John', email: 'john@example.com' },
  { id: 2, name: 'Jane', email: 'jane@example.com' },
];

<Table columns={columns} data={data} />;
```

## Styling

### CSS Classes

Components use BEM-like naming conventions:

- `ina-button` - Base button class
- `ina-button--primary` - Primary variant
- `ina-button--disabled` - Disabled state
- `ina-text-field` - Text field component
- `ina-text-field__input` - Input element
- `ina-text-field__label` - Label element

### Custom Styling

You can override component styles using CSS:

```css
.ina-button--primary {
  background-color: your-custom-color;
}
```

### Using with Tailwind CSS (Optional)

If you want to use Tailwind CSS utility classes alongside the design system:

1. Install Tailwind CSS in your project
2. Import color tokens:

```js
// tailwind.config.js
import iddsColorTokens from '@idds/react';

export default {
  theme: {
    extend: {
      colors: iddsColorTokens,
    },
  },
};
```

3. Use Tailwind classes for custom styling:

```jsx
<div className="bg-blue-500 text-white p-4">
  <Button>Click me</Button>
</div>
```

> **Note:** Tailwind CSS is **optional**. The design system works perfectly without it. Components are fully styled and functional using only the included CSS.

## TypeScript Support

All components are fully typed with TypeScript:

```tsx
import { TextField, type TextFieldProps } from '@idds/react';

const props: TextFieldProps = {
  label: 'Email',
  value: email,
  onChange: setEmail,
};
```

## Development

```bash
# Install dependencies
npm install

# Start development server
npm run dev

# Build for production
npm run build

# Type checking
npm run type-check

# Linting
npm run lint
```

## License

INA Digital © [Umar Faruq]
