npm package: @supap-labs/doc-management
Description: A React document management component library
Author: supap-labs
Latest version: 0.1.3

# @supap-labs/doc-management

> A React document management component library by **supap labs**.

[![npm version](https://img.shields.io/npm/v/%40supap-labs%2Fdoc-management)](https://www.npmjs.com/package/@supap-labs/doc-management)
[![license](https://img.shields.io/npm/l/%40supap-labs%2Fdoc-management)](./LICENSE)

---

## Installation

```bash
npm install @supap-labs/doc-management
# or
yarn add @supap-labs/doc-management
# or
pnpm add @supap-labs/doc-management
```

> **Peer dependencies:** `react >= 18` and `react-dom >= 18` must already be installed in your project.

> **Note:** The library automatically loads the [Inter](https://fonts.google.com/specimen/Inter) font from Google Fonts and applies it to all components.

---

## Components

### `<DocumentCard />`

A single document card with checkbox selection, inline edit and delete actions.

```tsx
import { DocumentCard } from '@supap-labs/doc-management';

<DocumentCard
  document={doc}
  checked={false}
  onCheck={(id, checked) => console.log(id, checked)}
  onSelect={(doc) => console.log('selected', doc)}
  onEdit={(doc) => console.log('edit', doc)}
  onDelete={(id) => console.log('delete', id)}
/>
```

#### Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `document` | `Document` | — | The document to display |
| `checked` | `boolean` | `false` | Checkbox checked state |
| `onCheck` | `(id, checked) => void` | — | Fired when checkbox changes |
| `onSelect` | `(doc) => void` | — | Fired when the card is clicked |
| `onEdit` | `(doc) => void` | — | Shows pencil icon when provided |
| `onDelete` | `(id) => void` | — | Shows trash icon when provided |
| `className` | `string` | `''` | Extra CSS class |

---

### `<DocumentList />`

Renders a list of `DocumentCard` components with loading and empty states.

```tsx
import { DocumentList } from '@supap-labs/doc-management';

<DocumentList
  documents={docs}
  isLoading={false}
  onSelect={(doc) => console.log('selected', doc)}
  onDelete={(id) => console.log('delete', id)}
  emptyMessage="No documents found."
/>
```

#### Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `documents` | `Document[]` | — | Array of documents to render |
| `isLoading` | `boolean` | `false` | Shows a loading indicator |
| `emptyMessage` | `string` | — | Message shown when list is empty |
| `onSelect` | `(doc) => void` | — | Passed to each `DocumentCard` |
| `onDelete` | `(id) => void` | — | Passed to each `DocumentCard` |
| `onDownload` | `(doc) => void` | — | Passed to each `DocumentCard` |
| `className` | `string` | `''` | Extra CSS class |

---

### `<DocumentUploader />`

Drag-and-drop / click-to-browse file uploader. Selected files are staged in a list with per-file removal before the upload is confirmed.

```tsx
import { DocumentUploader } from '@supap-labs/doc-management';

<DocumentUploader
  onUpload={async (files) => {
    // files: File[]
    await uploadToServer(files);
  }}
  accept=".pdf,.docx,.xlsx"
  multiple={true}
  maxSize={50 * 1024 * 1024} // 50 MB
/>
```

#### Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `onUpload` | `(files: File[]) => void \| Promise<void>` | — | Called when user confirms upload |
| `accept` | `string` | `'*'` | Passed to the file `<input>` (`accept` attribute) |
| `multiple` | `boolean` | `true` | Allow selecting multiple files |
| `maxSize` | `number` | — | Max file size in bytes; shows error if exceeded |
| `disabled` | `boolean` | `false` | Disables the uploader |
| `className` | `string` | `''` | Extra CSS class |

---

### `<DocumentViewer />`

In-place file preview supporting PDF, images, video, Word/Excel/PowerPoint (via MS Office Online), and plain text.

```tsx
import { DocumentViewer } from '@supap-labs/doc-management';

<DocumentViewer
  document={doc}
  onClose={() => setOpen(false)}
/>
```

#### Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `document` | `Document` | — | The document to preview |
| `onClose` | `() => void` | — | Shows a close button when provided |
| `className` | `string` | `''` | Extra CSS class |

**Supported preview types:**

| Type | Preview method |
|---|---|
| `pdf` | Native in-browser via `react-pdf` |
| `image` | `<img>` tag |
| `video` | `<video>` tag |
| `word` / `excel` / `powerpoint` | Embedded MS Office Online viewer |
| `text` | Sandboxed `<iframe>` |
| `other` | Download link fallback |

---

## Types

```ts
import type {
  Document,
  DocumentStatus,
  DocumentType,
  DocumentCardProps,
  DocumentListProps,
  DocumentUploaderProps,
  DocumentViewerProps,
} from '@supap-labs/doc-management';
```

### `Document`

```ts
interface Document {
  id: string;
  name: string;
  type: DocumentType;        // 'pdf' | 'word' | 'excel' | 'image' | 'text' | 'video' | 'powerpoint' | 'other'
  size: number;              // bytes
  status: DocumentStatus;    // 'draft' | 'pending' | 'approved' | 'rejected' | 'archived'
  url?: string;
  createdAt: Date | string;
  updatedAt: Date | string;
  uploadedBy?: string;
  tags?: string[];
  metadata?: Record<string, unknown>;
}
```

---

## Utilities

| Function | Description |
|---|---|
| `formatFileSize(bytes)` | Converts bytes to a human-readable string — e.g. `"1.2 MB"` |
| `getDocumentTypeFromFile(file)` | Infers `DocumentType` from a `File` object |
| `getDocumentTypeIcon(type, size?)` | Returns an SVG `React.ReactElement` icon for a given `DocumentType` |

---

## Development

```bash
# Install dependencies
npm install

# Start Storybook (component explorer)
npm run storybook

# Build the library (ESM + CJS + type declarations)
npm run build

# Build in watch mode
npm run dev

# Type-check without emitting
npm run type-check
```
---

## Contributing

Contributions are welcome! Here's how to get started:

1. **Fork** the repository and clone it locally
2. **Install dependencies**
   ```bash
   npm install
   ```
3. **Start Storybook** to develop and preview components interactively
   ```bash
   npm run storybook
   ```
4. **Make your changes** — please keep them focused and minimal
5. **Type-check** before committing
   ```bash
   npm run type-check
   ```
6. **Build** to verify the output is correct
   ```bash
   npm run build
   ```
7. **Open a pull request** with a clear description of what was changed and why

### Guidelines

- Follow the existing code style (TypeScript strict mode, inline styles, no external CSS dependencies)
- New components should include a Storybook story
- Keep peer dependencies out of `dependencies` — use `peerDependencies` instead
- Do not add runtime dependencies without discussion

### Commit Convention

This project follows [Conventional Commits](https://www.conventionalcommits.org/). Please use the format:

```
<type>(<scope>): <short description>
```

**Types:**

| Type | When to use |
|---|---|
| `feat` | New feature or component |
| `fix` | Bug fix |
| `chore` | Config, tooling, or dependency changes |
| `docs` | Documentation only |
| `refactor` | Code restructure with no behaviour change |
| `style` | Formatting, whitespace, or UI tweaks |
| `test` | Adding or updating tests |
| `perf` | Performance improvement |
| `revert` | Reverting a previous commit |

**Examples:**
```
feat(document-card): add checkbox and edit/delete actions
fix(document-uploader): reset input after file selection
style(document-card): switch font to Inter
chore(storybook): add Vite builder and addons
docs: update README with component props
```

---

### Reporting Issues

Please open an issue on GitHub with steps to reproduce, expected behaviour, and actual behaviour.

---

## License

MIT © [supap lab](https://github.com/Supap-Labs/Supap_doc_managment_FE_UI)