Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 71 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# @rdlabo/capacitor-codescanner

Capacitor Plugin for Code Scanner
<!-- rdlabo-docs-omit -->
[![npm version](https://badge.fury.io/js/@rdlabo%2Fcapacitor-codescanner.svg)](https://badge.fury.io/js/@rdlabo%2Fcapacitor-codescanner)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
<!-- /rdlabo-docs-omit -->

This is a barcode reader created for specific use cases. Unlike other Capacitor barcode reader plugins, this plugin opens a modal and performs scanning within it. Therefore, there is no need to manipulate web assets.
Barcode scanner for Capacitor that opens a native modal.

Unlike camera-preview based scanners, this plugin runs the camera inside a modal. You do not need to manage the camera view in your web assets. The plugin supports multiple barcode types and continuous multi-scan mode.

<!-- rdlabo-docs-omit -->
**Full documentation:** [https://docs.rdlabo.dev/projects/capacitor-codescanner](https://docs.rdlabo.dev/projects/capacitor-codescanner)
<!-- /rdlabo-docs-omit -->

## Install

Expand All @@ -11,63 +20,79 @@ npm install @rdlabo/capacitor-codescanner
npx cap sync
```


## Usage

```typescript
See [CodeScanner](./docs/code-scanner.md) to present the modal and receive scanned codes.

<!-- rdlabo-docs-omit -->
Register a listener before calling `present`. The listener receives each scanned code.

```ts
import { CodeScanner } from '@rdlabo/capacitor-codescanner';

// 基本的なQRコードスキャン
const scanQRCode = async () => {
await CodeScanner.addListener('CodeScannerCatchEvent', (event) => {
console.log('スキャンされたコード:', event.code);
console.log('Scanned code:', event.code);
});

await CodeScanner.present({
detectionX: 0.2,
detectionY: 0.35,
detectionWidth: 0.6,
detectionHeight: 0.15,
isMulti: false,
CodeTypes: ['qr']
CodeTypes: ['qr'],
});
};
```

To scan multiple barcode types continuously, enable multi-scan mode:

// 複数のバーコードタイプを連続スキャン
```ts
const scanMultipleCodes = async () => {
await CodeScanner.addListener('CodeScannerCatchEvent', (event) => {
console.log('スキャンされたコード:', event.code);
console.log('Scanned code:', event.code);
});

await CodeScanner.present({
detectionX: 0.1,
detectionY: 0.3,
detectionWidth: 0.8,
detectionHeight: 0.2,
isMulti: true,
CodeTypes: ['qr', 'code39', 'ean13', 'code128']
CodeTypes: ['qr', 'code39', 'ean13', 'code128'],
});
};
```

## Functions
<!-- /rdlabo-docs-omit -->

## When to use

Use this plugin when you want a ready-to-use scanning modal without building a custom camera UI. It is useful for:

- Scanning QR codes or barcodes on receipts, products, or tickets.
- Collecting multiple codes in one session with `isMulti: true`.
- Avoiding camera permission and preview wiring in your web code.

- **Automatic Light Control**: Flashlight automatically turns on when the scanner starts
- **Vibration**: Provides vibration feedback when a code is detected
- **Detection Area Display**: Visually displays the detection area with a red frame
- **Detected Code Highlighting**: Highlights detected codes with a red frame
- **Close Button**: You can close the scanner with the "✕" button in the upper right corner
- **Multiple Scan Mode**: You can continuously scan multiple codes with `isMulti: true`
## Features

- **Automatic light control**: turns on the flashlight in dark environments by default.
- **Vibration feedback**: vibrates when a code is detected.
- **Detection area overlay**: shows a red frame around the active scan area.
- **Detected code highlight**: draws a red frame around the detected code.
- **Close button**: a default close button in the upper right corner.
- **Multi-scan mode**: keeps scanning until the user closes the modal when `isMulti: true`.

## Platform notes

- **iOS and Android**: fully supported.
- **Web**: not supported because the plugin requires native camera access.

## API

<docgen-index>

* [`present(...)`](#present)
* [`addListener('CodeScannerCatchEvent', ...)`](#addlistenercodescannercatchevent-)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
- [`present(...)`](#present)
- [`addListener('CodeScannerCatchEvent', ...)`](#addlistenercodescannercatchevent-)
- [Interfaces](#interfaces)
- [Type Aliases](#type-aliases)

</docgen-index>

Expand All @@ -84,8 +109,7 @@ present(scannerOption: ScannerOption) => Promise<void>
| ------------------- | ------------------------------------------------------- |
| **`scannerOption`** | <code><a href="#scanneroption">ScannerOption</a></code> |

--------------------

---

### addListener('CodeScannerCatchEvent', ...)

Expand All @@ -100,37 +124,41 @@ addListener(eventName: 'CodeScannerCatchEvent', listenerFunc: (event: { code: st

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>

--------------------

---

### Interfaces


#### ScannerOption

| Prop | Type | Description |
| ------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **`detectionWidth`** | <code>number</code> | |
| **`detectionHeight`** | <code>number</code> | |
| **`enableCloseButton`** | <code>boolean</code> | Enable close button on the top left of the scanning area (default: true) |
| **`sheetScreenRatio`** | <code>number</code> | Specify the ratio of the scanning area (sheet modal size) to the screen size. Default is 0.9 for android, 1(pageSheet) for iOS. |
| **`metadataObjectTypes`** | <code>MetadataObjectTypes[]</code> | Specify the types of codes to recognize (default: ["qr", "code39", "ean13"]) |
| **`isMulti`** | <code>boolean</code> | Enable multi scan mode (default: false) |
| **`enableAutoLight`** | <code>boolean</code> | Enable auto light when environment is dark (default: true) |

| Prop | Type | Description |
| ----------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **`detectionWidth`** | <code>number</code> | Width of the detection area relative to the available width (0–1). Default is 0.4. |
| **`detectionHeight`** | <code>number</code> | Height of the detection area relative to the detection width. Default is 1 on iOS and 0.15–0.2 is typical on Android. |
| **`enableCloseButton`** | <code>boolean</code> | Enable close button on the top left of the scanning area (default: true) |
| **`sheetScreenRatio`** | <code>number</code> | Specify the ratio of the scanning area (sheet modal size) to the screen size. Default is 0.9 for android, 1(pageSheet) for iOS. |
| **`CodeTypes`** | <code>MetadataObjectTypes[]</code> | Specify the types of codes to recognize (default: ["qr", "code39", "ean13"]) |
| **`isMulti`** | <code>boolean</code> | Enable multi scan mode (default: false) |
| **`enableAutoLight`** | <code>boolean</code> | Enable auto light when environment is dark (default: true) |

#### PluginListenerHandle

| Prop | Type |
| ------------ | ----------------------------------------- |
| **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |


### Type Aliases


#### MetadataObjectTypes

<code>'aztec' | 'code128' | 'code39' | 'code39Mod43' | 'code93' | 'dataMatrix' | 'ean13' | 'ean8' | 'face' | 'interleaved2of5' | 'itf14' | 'pdf417' | 'qr' | 'upce' | 'catBody' | 'dogBody' | 'humanBody' | 'salientObject'</code>
<code>
'aztec' | 'code128' | 'code39' | 'code39Mod43' | 'code93' | 'dataMatrix' | 'ean13' | 'ean8' | 'face' |
'interleaved2of5' | 'itf14' | 'pdf417' | 'qr' | 'upce' | 'catBody' | 'dogBody' | 'humanBody' | 'salientObject'
</code>

</docgen-api>

<!-- rdlabo-docs-omit -->
## License

This project is licensed under the [MIT License](./LICENSE).
<!-- /rdlabo-docs-omit -->
53 changes: 53 additions & 0 deletions docs/code-scanner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# CodeScanner

`CodeScanner` opens a native scanner modal and delivers scanned values. Call this after [Installation](/docs/readme#installation). Register `addListener` before `present` so the first catch is not missed.

## present

```typescript
import { CodeScanner } from '@rdlabo/capacitor-codescanner';

const scanQRCode = async () => {
await CodeScanner.addListener('CodeScannerCatchEvent', (event) => {
console.log('Scanned code:', event.code);
});

await CodeScanner.present({
detectionWidth: 0.6,
detectionHeight: 0.15,
isMulti: false,
});
};

const scanMultipleCodes = async () => {
await CodeScanner.addListener('CodeScannerCatchEvent', (event) => {
console.log('Scanned code:', event.code);
});

await CodeScanner.present({
detectionWidth: 0.8,
detectionHeight: 0.2,
isMulti: true,
});
};
```

`isMulti: true` keeps the modal open so you can scan many codes. Option fields are on the [API](/docs/api#scanneroption) page.

> **Known limitation in v8.0.3:** the public TypeScript interface exposes `metadataObjectTypes`,
> but the native implementations still read the legacy `CodeTypes` key. Because the legacy key is
> not part of `ScannerOption`, omit code-type filtering with this release.

## addListener

```typescript
import { CodeScanner } from '@rdlabo/capacitor-codescanner';

const handle = await CodeScanner.addListener('CodeScannerCatchEvent', (event) => {
console.log('Scanned code:', event.code);
});

await handle.remove();
```

The payload is `{ code: string }`. Signatures are on the [API](/docs/api) page.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"android/src/main/",
"android/build.gradle",
"dist/",
"docs/",
"ios/Sources/",
"ios/Tests",
"Package.swift",
Expand Down