@scanupload/qr-code-generator-angular 0.1.9
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/README.md +139 -0
- package/dist/components/document-previewer.component.d.ts +17 -0
- package/dist/components/document-previewer.component.d.ts.map +1 -0
- package/dist/components/file-list.component.d.ts +10 -0
- package/dist/components/file-list.component.d.ts.map +1 -0
- package/dist/components/logo.component.d.ts +10 -0
- package/dist/components/logo.component.d.ts.map +1 -0
- package/dist/components/progress-bar.component.d.ts +7 -0
- package/dist/components/progress-bar.component.d.ts.map +1 -0
- package/dist/file-icons.d.ts +9 -0
- package/dist/file-icons.d.ts.map +1 -0
- package/dist/icons.d.ts +3 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +347 -0
- package/dist/index.es.js.map +1 -0
- package/dist/qr-code-generator.component.d.ts +29 -0
- package/dist/qr-code-generator.component.d.ts.map +1 -0
- package/dist/qrcode.d.ts +5 -0
- package/dist/qrcode.d.ts.map +1 -0
- package/dist/use-qr-code-core.d.ts +30 -0
- package/dist/use-qr-code-core.d.ts.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @scanupload/qr-code-generator-angular
|
|
2
|
+
|
|
3
|
+
Angular component wrapper for the ScanUpload QR Code Generator. It renders a QR
|
|
4
|
+
code, manages the live upload session, and shows uploaded-file previews using
|
|
5
|
+
the shared core runtime.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @scanupload/qr-code-generator-angular
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Peer dependencies:
|
|
14
|
+
|
|
15
|
+
- `@angular/core >= 20.2.0`
|
|
16
|
+
- `@angular/common >= 20.2.0`
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
The package ships standalone components, so import the component directly into
|
|
21
|
+
your standalone component or `NgModule`.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { Component } from '@angular/core';
|
|
25
|
+
import { QrCodeGeneratorComponent } from '@scanupload/qr-code-generator-angular';
|
|
26
|
+
|
|
27
|
+
@Component({
|
|
28
|
+
selector: 'app-root',
|
|
29
|
+
standalone: true,
|
|
30
|
+
imports: [QrCodeGeneratorComponent],
|
|
31
|
+
template: `
|
|
32
|
+
<sqg-qr-code-generator
|
|
33
|
+
sessionUrl="/api/session"
|
|
34
|
+
refreshTokenUrl="/api/token"
|
|
35
|
+
header="Upload documents"
|
|
36
|
+
[showHeader]="true"
|
|
37
|
+
></sqg-qr-code-generator>
|
|
38
|
+
`
|
|
39
|
+
})
|
|
40
|
+
export class AppComponent {}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Import the stylesheet once (e.g. in `styles.css` or the bootstrapped component):
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
@import '@scanupload/qr-code-generator-angular/dist/index.css';
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Backend Integration
|
|
50
|
+
|
|
51
|
+
- [ScanUpload.Api.Client](https://github.com/donaldasante/scanupload.api.client)
|
|
52
|
+
— ScanUpload backend proxy (.NET)
|
|
53
|
+
|
|
54
|
+
The component needs two backend endpoints:
|
|
55
|
+
|
|
56
|
+
| Endpoint | Method | Description |
|
|
57
|
+
| ----------------- | ------ | --------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `sessionUrl` | `POST` | Creates a ScanUpload session and returns `{ sessionId, accessToken, hubUrl, deviceLoginUrl }` |
|
|
59
|
+
| `refreshTokenUrl` | `POST` | Returns a fresh Bearer token `{ access_token, expires_in }` |
|
|
60
|
+
|
|
61
|
+
## Inputs
|
|
62
|
+
|
|
63
|
+
| Input | Type | Default | Required | Description |
|
|
64
|
+
| --------------------- | -------------------------------------------- | --------- | -------- | --------------------------------------------------------------------- |
|
|
65
|
+
| `sessionUrl` | `string` | — | Yes | Endpoint that creates a ScanUpload session. |
|
|
66
|
+
| `refreshTokenUrl` | `string` | — | Yes | Endpoint that refreshes the access token. |
|
|
67
|
+
| `header` | `string` | — | No | Text shown in the header when `showHeader` is enabled. |
|
|
68
|
+
| `showHeader` | `boolean` | `false` | No | Whether to render the header. |
|
|
69
|
+
| `showLogo` | `boolean` | `true` | No | Whether to overlay the ScanUpload logo on the QR code. |
|
|
70
|
+
| `clickQrCodeToReload` | `boolean` | `false` | No | Reload the session by clicking the QR code instead of using a button. |
|
|
71
|
+
| `filePreviewMode` | `"grid" \| "list"` | `"grid"` | No | Display files as tiles or a compact list. |
|
|
72
|
+
| `size` | `"small" \| "medium" \| "large" \| "xlarge"` | `"large"` | No | Controls the overall widget size. |
|
|
73
|
+
|
|
74
|
+
The `sessionUrl` and `refreshTokenUrl` inputs are reactive — changing them at
|
|
75
|
+
runtime updates the live session via the core `setOptions` API.
|
|
76
|
+
|
|
77
|
+
## Styling
|
|
78
|
+
|
|
79
|
+
The package ships a compiled stylesheet at `dist/index.css`.
|
|
80
|
+
|
|
81
|
+
```css
|
|
82
|
+
@import '@scanupload/qr-code-generator-angular/dist/index.css';
|
|
83
|
+
@import './my-overrides.css';
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Override after the package CSS so normal cascade rules apply.
|
|
87
|
+
|
|
88
|
+
```css
|
|
89
|
+
:root {
|
|
90
|
+
--sqg-primary: #1e3a5f;
|
|
91
|
+
--sqg-border-radius: 1rem;
|
|
92
|
+
--sqg-error-color: #dc2626;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sqg-root {
|
|
96
|
+
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## CSS custom properties
|
|
101
|
+
|
|
102
|
+
| Token | Default | Affects |
|
|
103
|
+
| --------------------- | ------------------------ | ----------------------------------------------------- |
|
|
104
|
+
| `--sqg-primary` | `#1e3a5f` | Spinner ring, connected logo, retry button background |
|
|
105
|
+
| `--sqg-error-color` | `#dc2626` | Error text and disconnected logo |
|
|
106
|
+
| `--sqg-border-color` | `#e5e7eb` | Borders around the QR wrapper and file cards |
|
|
107
|
+
| `--sqg-border-radius` | `0.75rem` | Root and QR wrapper corner radius |
|
|
108
|
+
| `--sqg-bg` | `#ffffff` | Widget background |
|
|
109
|
+
| `--sqg-overlay-bg` | `rgba(255,255,255,0.85)` | Loading and error overlays |
|
|
110
|
+
| `--sqg-text-color` | `#111827` | Main text |
|
|
111
|
+
| `--sqg-subtext-color` | `#6b7280` | Secondary text |
|
|
112
|
+
| `--sqg-spinner-size` | `2.5rem` | Spinner width and height |
|
|
113
|
+
| `--sqg-spinner-width` | `3px` | Spinner stroke width |
|
|
114
|
+
|
|
115
|
+
## File preview modes
|
|
116
|
+
|
|
117
|
+
### `grid`
|
|
118
|
+
|
|
119
|
+
Shows uploaded files as tiles with icons, optional image thumbnails, and upload
|
|
120
|
+
progress.
|
|
121
|
+
|
|
122
|
+
### `list`
|
|
123
|
+
|
|
124
|
+
Shows uploaded files as a compact list with thumbnail or file icon, file name,
|
|
125
|
+
and file size.
|
|
126
|
+
|
|
127
|
+
## Related exports
|
|
128
|
+
|
|
129
|
+
This package also re-exports:
|
|
130
|
+
|
|
131
|
+
- `useQrCodeCore` — signal-based controller wrapping the core runtime
|
|
132
|
+
- `LogoComponent`, `ProgressBarComponent`, `FileListComponent`,
|
|
133
|
+
`DocumentPreviewerComponent`
|
|
134
|
+
- Core types such as `UploadedFile`, `QrCodeGeneratorState`, and
|
|
135
|
+
`StorageAdapter`
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT © Donald Asante
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { DomSanitizer, type SafeHtml } from '@angular/platform-browser';
|
|
3
|
+
import type { UploadedFile } from '@scanupload/qr-code-generator-core';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare class DocumentPreviewerComponent {
|
|
6
|
+
private readonly sanitizer;
|
|
7
|
+
file: UploadedFile;
|
|
8
|
+
showExtension: boolean;
|
|
9
|
+
showRemoveButton: boolean;
|
|
10
|
+
removeFile: EventEmitter<string>;
|
|
11
|
+
protected readonly removeIcon: SafeHtml;
|
|
12
|
+
constructor(sanitizer: DomSanitizer);
|
|
13
|
+
protected get extension(): string;
|
|
14
|
+
protected get iconSvg(): SafeHtml;
|
|
15
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DocumentPreviewerComponent, never>;
|
|
16
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DocumentPreviewerComponent, "sqg-document-previewer", never, { "file": { "alias": "file"; "required": true; }; "showExtension": { "alias": "showExtension"; "required": false; }; "showRemoveButton": { "alias": "showRemoveButton"; "required": false; }; }, { "removeFile": "removeFile"; }, never, never, true, never>;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-previewer.component.d.ts","sourceRoot":"","sources":["../../src/components/document-previewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,YAAY,EAAiB,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAKvE,qBAuCa,0BAA0B;IAQvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAPX,IAAI,EAAG,YAAY,CAAC;IACtC,aAAa,UAAQ;IACrB,gBAAgB,UAAS;IACxB,UAAU,uBAA8B;IAElD,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC;gBAEX,SAAS,EAAE,YAAY;IAIpD,SAAS,KAAK,SAAS,IAAI,MAAM,CAEhC;IAED,SAAS,KAAK,OAAO,IAAI,QAAQ,CAEhC;CACJ"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DomSanitizer, type SafeHtml } from '@angular/platform-browser';
|
|
2
|
+
import type { UploadedFile } from '@scanupload/qr-code-generator-core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class FileListComponent {
|
|
5
|
+
files: UploadedFile[];
|
|
6
|
+
protected readonly docIcon: SafeHtml;
|
|
7
|
+
constructor(sanitizer: DomSanitizer);
|
|
8
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FileListComponent, never>;
|
|
9
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FileListComponent, "sqg-file-list", never, { "files": { "alias": "files"; "required": false; }; }, {}, never, never, true, never>;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-list.component.d.ts","sourceRoot":"","sources":["../../src/components/file-list.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAGvE,qBA0Ba,iBAAiB;IACjB,KAAK,EAAE,YAAY,EAAE,CAAM;IAEpC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;gBAEzB,SAAS,EAAE,YAAY;CAGtC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DomSanitizer, type SafeHtml } from '@angular/platform-browser';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class LogoComponent {
|
|
4
|
+
isConnected: boolean;
|
|
5
|
+
protected readonly svg: SafeHtml;
|
|
6
|
+
constructor(sanitizer: DomSanitizer);
|
|
7
|
+
protected get cssClass(): string;
|
|
8
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LogoComponent, never>;
|
|
9
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LogoComponent, "sqg-logo", never, { "isConnected": { "alias": "isConnected"; "required": false; }; }, {}, never, never, true, never>;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logo.component.d.ts","sourceRoot":"","sources":["../../src/components/logo.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAGxE,qBAMa,aAAa;IACb,WAAW,UAAS;IAE7B,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;gBAErB,SAAS,EAAE,YAAY;IAInC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAE/B;CACJ"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
export declare class ProgressBarComponent {
|
|
3
|
+
progress: number;
|
|
4
|
+
protected get rounded(): number;
|
|
5
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProgressBarComponent, never>;
|
|
6
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ProgressBarComponent, "sqg-progress-bar", never, { "progress": { "alias": "progress"; "required": false; }; }, {}, never, never, true, never>;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-bar.component.d.ts","sourceRoot":"","sources":["../../src/components/progress-bar.component.ts"],"names":[],"mappings":"AAEA,qBAgBa,oBAAoB;IACpB,QAAQ,SAAK;IAEtB,SAAS,KAAK,OAAO,IAAI,MAAM,CAE9B;CACJ"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an inline SVG string for a file-type icon based on the extension.
|
|
3
|
+
* Uses the same Lucide icons and colour mapping as the React DocumentPreviewer.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getFileIconSvg(extension: string, size?: number): string;
|
|
6
|
+
/** Generic document icon for list-view when no thumbnail is available. */
|
|
7
|
+
export declare function getGenericDocIconSvg(size?: number): string;
|
|
8
|
+
/** Extract the lowercase file extension from a file name. */
|
|
9
|
+
export declare function getFileExtension(filename: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-icons.d.ts","sourceRoot":"","sources":["../src/file-icons.ts"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAqFnE;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,SAAK,GAAG,MAAM,CAEtD;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzD"}
|
package/dist/icons.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const REDO_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 512 512\" fill=\"currentColor\"><path d=\"M500.33 0h-47.41a12 12 0 0 0-12 12.57l4 82.02A247.42 247.42 0 0 0 256 8C119.34 8 8 119.34 8 256s111.34 248 248 248 248-111.34 248-248c0-36.27-7.8-70.75-21.83-101.78a12 12 0 0 0-22.09 9.35A207.59 207.59 0 0 1 464 256c0 114.69-93.31 208-208 208S48 370.69 48 256 141.31 48 256 48a207.45 207.45 0 0 1 155.7 70.28l-94.27-4.49A12 12 0 0 0 316.86 126v47.41a12 12 0 0 0 12 12h171.47a12 12 0 0 0 12-12V12.57A12 12 0 0 0 500.33 0z\"/></svg>";
|
|
2
|
+
export declare const QR_SCANNER_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9.5 6.5v3h-3v-3h3M11 5H5v6h6V5zm-1.5 9.5v3h-3v-3h3M11 13H5v6h6v-6zm6.5-6.5v3h-3v-3h3M19 5h-6v6h6V5zm-6 8h1.5v1.5H13V13zm1.5 1.5H16V16h-1.5v-1.5zM16 13h1.5v1.5H16V13zm-3 3h1.5v1.5H13V16zm1.5 1.5H16V19h-1.5v-1.5zM16 16h1.5v1.5H16V16zm1.5-1.5H19V16h-1.5v-1.5zm0 3H19V19h-1.5v-1.5zM22 7h-2V4h-3V2h5v5zm0 15v-5h-2v3h-3v2h5zM2 22h5v-2H4v-3H2v5zM2 2v5h2V4h3V2H2z\"/></svg>";
|
|
3
|
+
export declare const REMOVE_SVG = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"m15 9-6 6\"/><path d=\"m9 9 6 6\"/></svg>";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,gjBAAoiB,CAAC;AAE1jB,eAAO,MAAM,cAAc,mdAA2c,CAAC;AAEve,eAAO,MAAM,UAAU,0TAA0R,CAAC"}
|
package/dist/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@keyframes sqg-spin{to{transform:rotate(360deg)}}.sqg-root{position:relative;overflow:hidden;padding:.5rem}.sqg-overlay{position:absolute;inset:0;background:#ffffffe6;display:flex;align-items:center;justify-content:center;border-radius:.375rem;z-index:10}.sqg-loading-content{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem}.sqg-spinner{border-radius:50%;height:1.5rem;width:1.5rem;border:2px dashed transparent;border-top-color:#1e3a5f;animation:sqg-spin 1s linear infinite}.sqg-loading-text{color:#111827;font-size:.875rem}.sqg-error-content{display:flex;flex-direction:column;align-items:center;text-align:center;margin-top:1.25rem;gap:.5rem}.sqg-error-text{color:#111827;font-size:.75rem}.sqg-retry-btn{background:#93c5fd;color:#fff;padding:.25rem .5rem;border-radius:.375rem;border:none;cursor:pointer;transition:background .15s;display:flex;align-items:center}.sqg-retry-btn:hover{background:#3b82f6}.sqg-content{display:flex;flex-direction:column;align-items:center;text-align:center}.sqg-header{margin-bottom:.5rem}.sqg-header-title{font-size:1.25rem;font-weight:600;color:#4b5563}.sqg-qr-wrapper{background:#fff;padding:.5rem;border-radius:1rem;border:2px dashed #d1d5db;display:flex;align-items:center;justify-content:center;transition:box-shadow .3s,transform .3s;position:relative}.sqg-qr-wrapper:hover{box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;transform:scale(1.05)}.sqg-qr-inner{position:relative;display:inline-block;width:100%;height:100%}.sqg-qr-code{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.sqg-qr-code svg{width:100%;height:100%}.sqg-logo-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}.sqg-logo{width:1.5rem;height:1.5rem;color:#fff;border-radius:.5rem;padding:.25rem;display:flex;align-items:center;justify-content:center}.sqg-logo--disconnected{background:linear-gradient(to right,#dc2626,#991b1b)}.sqg-logo--connected{background:linear-gradient(to right,#bbf7d0,#22c55e)}.sqg-reload-section{display:flex;flex-direction:row;margin-top:.75rem}.sqg-reload-btn{background:#6b7280;color:#fff;padding:.5rem 1rem;border-radius:.375rem;display:flex;align-items:center;gap:.75rem;font-size:.875rem;border:none;cursor:pointer;transition:background .15s}.sqg-reload-btn:hover{background:#1e40af}.sqg-hint-text{color:#6b7280;font-size:.875rem}.sqg-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sqg-file-grid{display:flex;flex-direction:row;justify-content:center;gap:.25rem;flex-wrap:wrap}.sqg-file-card{display:flex;flex-direction:column;align-items:center;margin-top:.5rem;gap:.25rem}.sqg-file-inner{display:flex;max-width:160px;cursor:default;flex-direction:column;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #e5e7eb;background:#fff;padding:.75rem;box-shadow:0 1px 2px #0000000d;transition:background .2s,box-shadow .2s}.sqg-file-inner:hover{background:#f9fafb;box-shadow:0 4px 6px #00000012}.sqg-thumb-wrap{height:3rem;width:5rem;overflow:hidden;border-radius:.25rem;transition:transform .2s}.sqg-file-inner:hover .sqg-thumb-wrap{transform:scale(1.1)}.sqg-thumb-img{height:100%;width:100%;object-fit:cover}.sqg-icon-wrap{margin-bottom:.5rem;transition:transform .2s}.sqg-file-inner:hover .sqg-icon-wrap{transform:scale(1.1)}.sqg-ext-badge{font-size:1rem;padding:0 .25rem;text-align:center;font-weight:500;word-break:break-all}.sqg-ext-badge span{display:inline-block;border-radius:.25rem;background:#f3f4f6;padding:.125rem .5rem;color:#374151}.sqg-file-info{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:.25rem;padding:.5rem}.sqg-file-meta{margin-top:.25rem}.sqg-file-name{width:6.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.75rem;font-weight:500;color:#1f2937}.sqg-file-size{text-align:start;font-size:.75rem;color:#6b7280}.sqg-file-list{width:100%}.sqg-file-list-inner{display:flex;flex-direction:column;border-radius:.5rem;border:1px solid #e5e7eb;background:#fff;overflow:hidden}.sqg-file-row{display:flex;align-items:center;gap:.5rem;padding:.5rem;border-top:1px solid #e5e7eb}.sqg-file-row:first-child{border-top:none}.sqg-list-thumb{width:3rem;height:3rem;flex-shrink:0;overflow:hidden;border-radius:.25rem;background:#f3f4f6;display:flex;align-items:center;justify-content:center;color:#6b7280}.sqg-list-thumb img{width:100%;height:100%;object-fit:cover}.sqg-list-info{display:flex;flex-direction:column;flex:1;min-width:0}.sqg-list-name{font-size:.75rem;font-weight:500;color:#1f2937;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:15rem}.sqg-list-size{font-size:.75rem;color:#6b7280}.sqg-progress-wrap{margin-top:.75rem;width:100%}.sqg-progress-labels{margin-bottom:.5rem;display:flex;justify-content:space-between}.sqg-progress-label{font-size:.875rem;font-weight:500;color:#374151}.sqg-progress-track{height:.625rem;width:100%;border-radius:9999px;background:#e5e7eb}.sqg-progress-fill{height:.625rem;border-radius:9999px;background:#10b981;box-shadow:0 0 8px #10b98166;transition:width .3s ease-out}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
export { QrCodeGeneratorComponent } from './qr-code-generator.component';
|
|
3
|
+
export type { FilePreviewMode, QrCodeSize } from './qr-code-generator.component';
|
|
4
|
+
export { LogoComponent } from './components/logo.component';
|
|
5
|
+
export { ProgressBarComponent } from './components/progress-bar.component';
|
|
6
|
+
export { FileListComponent } from './components/file-list.component';
|
|
7
|
+
export { DocumentPreviewerComponent } from './components/document-previewer.component';
|
|
8
|
+
export { useQrCodeCore } from './use-qr-code-core';
|
|
9
|
+
export type { QrCodeCoreController, UseQrCodeCoreOptions } from './use-qr-code-core';
|
|
10
|
+
export type { SessionResponse, TokenResponse, UploadedFile, QrCodeGeneratorState, StorageAdapter, QrCodeGeneratorCoreOptions } from '@scanupload/qr-code-generator-core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAGvF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAGrF,YAAY,EACR,eAAe,EACf,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,0BAA0B,EAC7B,MAAM,oCAAoC,CAAC"}
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import * as e from "@angular/core";
|
|
2
|
+
import { EventEmitter as y, signal as q, effect as S } from "@angular/core";
|
|
3
|
+
import * as u from "@angular/platform-browser";
|
|
4
|
+
import { createElement as b, File as v, FileCode as p, FileJson as E, FileType as H, FileArchive as k, FileAudio as F, FileVideo as M, FileImage as V, FileDigit as L, FileText as _, Presentation as Q, FileSpreadsheet as x } from "lucide";
|
|
5
|
+
import { QrCodeGeneratorCore as z } from "@scanupload/qr-code-generator-core";
|
|
6
|
+
import I from "qrcode";
|
|
7
|
+
const U = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 512 512" fill="currentColor"><path d="M500.33 0h-47.41a12 12 0 0 0-12 12.57l4 82.02A247.42 247.42 0 0 0 256 8C119.34 8 8 119.34 8 256s111.34 248 248 248 248-111.34 248-248c0-36.27-7.8-70.75-21.83-101.78a12 12 0 0 0-22.09 9.35A207.59 207.59 0 0 1 464 256c0 114.69-93.31 208-208 208S48 370.69 48 256 141.31 48 256 48a207.45 207.45 0 0 1 155.7 70.28l-94.27-4.49A12 12 0 0 0 316.86 126v47.41a12 12 0 0 0 12 12h171.47a12 12 0 0 0 12-12V12.57A12 12 0 0 0 500.33 0z"/></svg>', R = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M9.5 6.5v3h-3v-3h3M11 5H5v6h6V5zm-1.5 9.5v3h-3v-3h3M11 13H5v6h6v-6zm6.5-6.5v3h-3v-3h3M19 5h-6v6h6V5zm-6 8h1.5v1.5H13V13zm1.5 1.5H16V16h-1.5v-1.5zM16 13h1.5v1.5H16V13zm-3 3h1.5v1.5H13V16zm1.5 1.5H16V19h-1.5v-1.5zM16 16h1.5v1.5H16V16zm1.5-1.5H19V16h-1.5v-1.5zm0 3H19V19h-1.5v-1.5zM22 7h-2V4h-3V2h5v5zm0 15v-5h-2v3h-3v2h5zM2 22h5v-2H4v-3H2v5zM2 2v5h2V4h3V2H2z"/></svg>', D = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>', a = class a {
|
|
8
|
+
constructor(t) {
|
|
9
|
+
this.isConnected = !1, this.svg = t.bypassSecurityTrustHtml(R);
|
|
10
|
+
}
|
|
11
|
+
get cssClass() {
|
|
12
|
+
return this.isConnected ? "sqg-logo sqg-logo--connected" : "sqg-logo sqg-logo--disconnected";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
a.ɵfac = function(n) {
|
|
16
|
+
return new (n || a)(e.ɵɵdirectiveInject(u.DomSanitizer));
|
|
17
|
+
}, a.ɵcmp = /* @__PURE__ */ e.ɵɵdefineComponent({ type: a, selectors: [["sqg-logo"]], inputs: { isConnected: "isConnected" }, decls: 1, vars: 3, consts: [[3, "innerHTML"]], template: function(n, i) {
|
|
18
|
+
n & 1 && e.ɵɵdomElement(0, "span", 0), n & 2 && (e.ɵɵclassMap(i.cssClass), e.ɵɵdomProperty("innerHTML", i.svg, e.ɵɵsanitizeHtml));
|
|
19
|
+
}, encapsulation: 2, changeDetection: 0 });
|
|
20
|
+
let g = a;
|
|
21
|
+
function r(o, t, n) {
|
|
22
|
+
const i = b(o);
|
|
23
|
+
return i.setAttribute("width", String(t)), i.setAttribute("height", String(t)), i.setAttribute("stroke", n), i.outerHTML;
|
|
24
|
+
}
|
|
25
|
+
function G(o, t = 24) {
|
|
26
|
+
switch (o.toLowerCase()) {
|
|
27
|
+
// Documents
|
|
28
|
+
case "pdf":
|
|
29
|
+
return r(v, t, "#ef4444");
|
|
30
|
+
case "doc":
|
|
31
|
+
case "docx":
|
|
32
|
+
return r(_, t, "#3b82f6");
|
|
33
|
+
case "xls":
|
|
34
|
+
case "xlsx":
|
|
35
|
+
return r(x, t, "#16a34a");
|
|
36
|
+
case "csv":
|
|
37
|
+
return r(x, t, "#22c55e");
|
|
38
|
+
case "ppt":
|
|
39
|
+
case "pptx":
|
|
40
|
+
return r(Q, t, "#f97316");
|
|
41
|
+
case "txt":
|
|
42
|
+
case "rtf":
|
|
43
|
+
return r(_, t, "#4b5563");
|
|
44
|
+
case "md":
|
|
45
|
+
return r(L, t, "#4b5563");
|
|
46
|
+
// Images
|
|
47
|
+
case "jpg":
|
|
48
|
+
case "jpeg":
|
|
49
|
+
case "png":
|
|
50
|
+
case "gif":
|
|
51
|
+
case "svg":
|
|
52
|
+
case "bmp":
|
|
53
|
+
case "webp":
|
|
54
|
+
case "ico":
|
|
55
|
+
return r(V, t, "#a855f7");
|
|
56
|
+
// Video
|
|
57
|
+
case "mp4":
|
|
58
|
+
case "avi":
|
|
59
|
+
case "mov":
|
|
60
|
+
case "wmv":
|
|
61
|
+
case "flv":
|
|
62
|
+
case "webm":
|
|
63
|
+
case "mkv":
|
|
64
|
+
return r(M, t, "#9333ea");
|
|
65
|
+
// Audio
|
|
66
|
+
case "mp3":
|
|
67
|
+
case "wav":
|
|
68
|
+
case "ogg":
|
|
69
|
+
case "flac":
|
|
70
|
+
case "m4a":
|
|
71
|
+
case "aac":
|
|
72
|
+
return r(F, t, "#ec4899");
|
|
73
|
+
// Archives
|
|
74
|
+
case "zip":
|
|
75
|
+
case "rar":
|
|
76
|
+
case "7z":
|
|
77
|
+
case "tar":
|
|
78
|
+
case "gz":
|
|
79
|
+
case "bz2":
|
|
80
|
+
return r(k, t, "#ca8a04");
|
|
81
|
+
// Code
|
|
82
|
+
case "js":
|
|
83
|
+
case "jsx":
|
|
84
|
+
return r(p, t, "#eab308");
|
|
85
|
+
case "ts":
|
|
86
|
+
case "tsx":
|
|
87
|
+
return r(H, t, "#2563eb");
|
|
88
|
+
case "html":
|
|
89
|
+
case "htm":
|
|
90
|
+
return r(p, t, "#ea580c");
|
|
91
|
+
case "css":
|
|
92
|
+
return r(p, t, "#60a5fa");
|
|
93
|
+
case "json":
|
|
94
|
+
return r(E, t, "#374151");
|
|
95
|
+
case "xml":
|
|
96
|
+
case "yml":
|
|
97
|
+
case "yaml":
|
|
98
|
+
return r(p, t, "#4b5563");
|
|
99
|
+
default:
|
|
100
|
+
return r(v, t, "#6b7280");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function j(o = 24) {
|
|
104
|
+
return r(v, o, "#6b7280");
|
|
105
|
+
}
|
|
106
|
+
function P(o) {
|
|
107
|
+
const t = o.split(".");
|
|
108
|
+
return t.length > 1 ? t.pop().toLowerCase() : "";
|
|
109
|
+
}
|
|
110
|
+
const l = class l {
|
|
111
|
+
constructor() {
|
|
112
|
+
this.progress = 0;
|
|
113
|
+
}
|
|
114
|
+
get rounded() {
|
|
115
|
+
return Math.round(this.progress || 0);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
l.ɵfac = function(n) {
|
|
119
|
+
return new (n || l)();
|
|
120
|
+
}, l.ɵcmp = /* @__PURE__ */ e.ɵɵdefineComponent({ type: l, selectors: [["sqg-progress-bar"]], inputs: { progress: "progress" }, decls: 8, vars: 3, consts: [[1, "sqg-progress-wrap"], [1, "sqg-progress-labels"], [1, "sqg-progress-label"], [1, "sqg-progress-track"], [1, "sqg-progress-fill"]], template: function(n, i) {
|
|
121
|
+
n & 1 && (e.ɵɵdomElementStart(0, "div", 0)(1, "div", 1)(2, "span", 2), e.ɵɵtext(3, "Uploading..."), e.ɵɵdomElementEnd(), e.ɵɵdomElementStart(4, "span", 2), e.ɵɵtext(5), e.ɵɵdomElementEnd()(), e.ɵɵdomElementStart(6, "div", 3), e.ɵɵdomElement(7, "div", 4), e.ɵɵdomElementEnd()()), n & 2 && (e.ɵɵadvance(5), e.ɵɵtextInterpolate1("", i.rounded, "%"), e.ɵɵadvance(2), e.ɵɵstyleProp("width", i.progress || 0, "%"));
|
|
122
|
+
}, encapsulation: 2, changeDetection: 0 });
|
|
123
|
+
let h = l;
|
|
124
|
+
function B(o, t) {
|
|
125
|
+
if (o & 1 && (e.ɵɵelementStart(0, "div", 2), e.ɵɵelement(1, "img", 9), e.ɵɵelementEnd()), o & 2) {
|
|
126
|
+
const n = e.ɵɵnextContext();
|
|
127
|
+
e.ɵɵadvance(), e.ɵɵproperty("src", "data:" + n.file.type + ";base64," + n.file.thumbnailBase64, e.ɵɵsanitizeUrl)("alt", n.file.name);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function A(o, t) {
|
|
131
|
+
if (o & 1 && (e.ɵɵelementStart(0, "div", 11)(1, "span"), e.ɵɵtext(2), e.ɵɵelementEnd()()), o & 2) {
|
|
132
|
+
const n = e.ɵɵnextContext(2);
|
|
133
|
+
e.ɵɵadvance(2), e.ɵɵtextInterpolate(n.extension.toUpperCase());
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function O(o, t) {
|
|
137
|
+
if (o & 1 && (e.ɵɵelement(0, "div", 10), e.ɵɵconditionalCreate(1, A, 3, 1, "div", 11)), o & 2) {
|
|
138
|
+
const n = e.ɵɵnextContext();
|
|
139
|
+
e.ɵɵproperty("innerHTML", n.iconSvg, e.ɵɵsanitizeHtml), e.ɵɵattribute("data-filetype", n.extension), e.ɵɵadvance(), e.ɵɵconditional(n.showExtension && n.extension ? 1 : -1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function $(o, t) {
|
|
143
|
+
if (o & 1) {
|
|
144
|
+
const n = e.ɵɵgetCurrentView();
|
|
145
|
+
e.ɵɵelementStart(0, "button", 12), e.ɵɵlistener("click", function() {
|
|
146
|
+
e.ɵɵrestoreView(n);
|
|
147
|
+
const s = e.ɵɵnextContext();
|
|
148
|
+
return e.ɵɵresetView(s.removeFile.emit(s.file.id));
|
|
149
|
+
}), e.ɵɵelementEnd();
|
|
150
|
+
}
|
|
151
|
+
if (o & 2) {
|
|
152
|
+
const n = e.ɵɵnextContext();
|
|
153
|
+
e.ɵɵproperty("innerHTML", n.removeIcon, e.ɵɵsanitizeHtml);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const c = class c {
|
|
157
|
+
constructor(t) {
|
|
158
|
+
this.sanitizer = t, this.showExtension = !0, this.showRemoveButton = !1, this.removeFile = new y(), this.removeIcon = t.bypassSecurityTrustHtml(D);
|
|
159
|
+
}
|
|
160
|
+
get extension() {
|
|
161
|
+
return P(this.file.name);
|
|
162
|
+
}
|
|
163
|
+
get iconSvg() {
|
|
164
|
+
return this.sanitizer.bypassSecurityTrustHtml(G(this.extension, 40));
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
c.ɵfac = function(n) {
|
|
168
|
+
return new (n || c)(e.ɵɵdirectiveInject(u.DomSanitizer));
|
|
169
|
+
}, c.ɵcmp = /* @__PURE__ */ e.ɵɵdefineComponent({ type: c, selectors: [["sqg-document-previewer"]], inputs: { file: "file", showExtension: "showExtension", showRemoveButton: "showRemoveButton" }, outputs: { removeFile: "removeFile" }, decls: 12, vars: 6, consts: [[1, "sqg-file-card"], [1, "sqg-file-inner"], [1, "sqg-thumb-wrap"], [1, "sqg-file-info"], [1, "sqg-file-meta"], [1, "sqg-file-name", 3, "title"], [1, "sqg-file-size"], ["aria-label", "Remove File", 1, "sqg-remove-btn", 3, "innerHTML"], [3, "progress"], [1, "sqg-thumb-img", 3, "src", "alt"], [1, "sqg-icon-wrap", 3, "innerHTML"], [1, "sqg-ext-badge"], ["aria-label", "Remove File", 1, "sqg-remove-btn", 3, "click", "innerHTML"]], template: function(n, i) {
|
|
170
|
+
n & 1 && (e.ɵɵelementStart(0, "div", 0)(1, "div", 1), e.ɵɵconditionalCreate(2, B, 2, 2, "div", 2)(3, O, 2, 3), e.ɵɵelementStart(4, "div", 3)(5, "div", 4)(6, "p", 5), e.ɵɵtext(7), e.ɵɵelementEnd(), e.ɵɵelementStart(8, "p", 6), e.ɵɵtext(9), e.ɵɵelementEnd()(), e.ɵɵconditionalCreate(10, $, 1, 1, "button", 7), e.ɵɵelementEnd(), e.ɵɵelement(11, "sqg-progress-bar", 8), e.ɵɵelementEnd()()), n & 2 && (e.ɵɵadvance(2), e.ɵɵconditional(i.file.thumbnailBase64 ? 2 : 3), e.ɵɵadvance(4), e.ɵɵproperty("title", i.file.name), e.ɵɵadvance(), e.ɵɵtextInterpolate(i.file.name), e.ɵɵadvance(2), e.ɵɵtextInterpolate1("(", (i.file.size / 1024).toFixed(1), " KB)"), e.ɵɵadvance(), e.ɵɵconditional(i.showRemoveButton ? 10 : -1), e.ɵɵadvance(), e.ɵɵproperty("progress", i.file.progress));
|
|
171
|
+
}, dependencies: [h], encapsulation: 2, changeDetection: 0 });
|
|
172
|
+
let f = c;
|
|
173
|
+
const N = (o, t) => t.id;
|
|
174
|
+
function K(o, t) {
|
|
175
|
+
if (o & 1 && e.ɵɵdomElement(0, "img", 4), o & 2) {
|
|
176
|
+
const n = e.ɵɵnextContext().$implicit;
|
|
177
|
+
e.ɵɵdomProperty("src", "data:" + n.type + ";base64," + n.thumbnailBase64, e.ɵɵsanitizeUrl)("alt", n.name);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function J(o, t) {
|
|
181
|
+
if (o & 1 && e.ɵɵdomElement(0, "span", 5), o & 2) {
|
|
182
|
+
const n = e.ɵɵnextContext(2);
|
|
183
|
+
e.ɵɵdomProperty("innerHTML", n.docIcon, e.ɵɵsanitizeHtml);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function W(o, t) {
|
|
187
|
+
if (o & 1 && (e.ɵɵdomElementStart(0, "div", 2)(1, "div", 3), e.ɵɵconditionalCreate(2, K, 1, 2, "img", 4)(3, J, 1, 1, "span", 5), e.ɵɵdomElementEnd(), e.ɵɵdomElementStart(4, "div", 6)(5, "span", 7), e.ɵɵtext(6), e.ɵɵdomElementEnd(), e.ɵɵdomElementStart(7, "span", 8), e.ɵɵtext(8), e.ɵɵdomElementEnd()()()), o & 2) {
|
|
188
|
+
const n = t.$implicit;
|
|
189
|
+
e.ɵɵadvance(2), e.ɵɵconditional(n.thumbnailBase64 ? 2 : 3), e.ɵɵadvance(3), e.ɵɵdomProperty("title", n.name), e.ɵɵadvance(), e.ɵɵtextInterpolate(n.name), e.ɵɵadvance(2), e.ɵɵtextInterpolate1("", (n.size / 1024).toFixed(1), " KB");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const d = class d {
|
|
193
|
+
constructor(t) {
|
|
194
|
+
this.files = [], this.docIcon = t.bypassSecurityTrustHtml(j(24));
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
d.ɵfac = function(n) {
|
|
198
|
+
return new (n || d)(e.ɵɵdirectiveInject(u.DomSanitizer));
|
|
199
|
+
}, d.ɵcmp = /* @__PURE__ */ e.ɵɵdefineComponent({ type: d, selectors: [["sqg-file-list"]], inputs: { files: "files" }, decls: 4, vars: 0, consts: [[1, "sqg-file-list"], [1, "sqg-file-list-inner"], [1, "sqg-file-row"], [1, "sqg-list-thumb"], [3, "src", "alt"], [3, "innerHTML"], [1, "sqg-list-info"], [1, "sqg-list-name", 3, "title"], [1, "sqg-list-size"]], template: function(n, i) {
|
|
200
|
+
n & 1 && (e.ɵɵdomElementStart(0, "div", 0)(1, "div", 1), e.ɵɵrepeaterCreate(2, W, 9, 4, "div", 2, N), e.ɵɵdomElementEnd()()), n & 2 && (e.ɵɵadvance(2), e.ɵɵrepeater(i.files));
|
|
201
|
+
}, encapsulation: 2, changeDetection: 0 });
|
|
202
|
+
let C = d;
|
|
203
|
+
function X(o) {
|
|
204
|
+
const t = new z({
|
|
205
|
+
sessionUrl: o.sessionUrl,
|
|
206
|
+
refreshTokenUrl: o.refreshTokenUrl,
|
|
207
|
+
storage: o.storage
|
|
208
|
+
}), n = q(t.getState());
|
|
209
|
+
let i = null;
|
|
210
|
+
return {
|
|
211
|
+
state: n.asReadonly(),
|
|
212
|
+
start() {
|
|
213
|
+
i = t.subscribe(() => n.set(t.getState())), n.set(t.getState()), t.start();
|
|
214
|
+
},
|
|
215
|
+
retrySession: () => t.retrySession(),
|
|
216
|
+
setOptions: (s) => t.setOptions(s),
|
|
217
|
+
dispose() {
|
|
218
|
+
i?.(), i = null, t.dispose();
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
async function Y(o, t = 200) {
|
|
223
|
+
return I.toString(o, {
|
|
224
|
+
type: "svg",
|
|
225
|
+
width: t,
|
|
226
|
+
margin: 2,
|
|
227
|
+
errorCorrectionLevel: "L"
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
const T = () => [], Z = (o, t) => t.id;
|
|
231
|
+
function ee(o, t) {
|
|
232
|
+
o & 1 && (e.ɵɵelementStart(0, "div", 1)(1, "div", 12), e.ɵɵelement(2, "div", 13), e.ɵɵelementStart(3, "p", 14), e.ɵɵtext(4, "Loading..."), e.ɵɵelementEnd()()());
|
|
233
|
+
}
|
|
234
|
+
function te(o, t) {
|
|
235
|
+
if (o & 1) {
|
|
236
|
+
const n = e.ɵɵgetCurrentView();
|
|
237
|
+
e.ɵɵelementStart(0, "div", 1)(1, "div", 15)(2, "p", 16), e.ɵɵtext(3, "Cannot create session"), e.ɵɵelementEnd(), e.ɵɵelementStart(4, "button", 17), e.ɵɵlistener("click", function() {
|
|
238
|
+
e.ɵɵrestoreView(n);
|
|
239
|
+
const s = e.ɵɵnextContext();
|
|
240
|
+
return e.ɵɵresetView(s.retry());
|
|
241
|
+
}), e.ɵɵelementEnd()()();
|
|
242
|
+
}
|
|
243
|
+
if (o & 2) {
|
|
244
|
+
const n = e.ɵɵnextContext();
|
|
245
|
+
e.ɵɵadvance(4), e.ɵɵproperty("innerHTML", n.redoIcon, e.ɵɵsanitizeHtml);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function ne(o, t) {
|
|
249
|
+
if (o & 1 && (e.ɵɵelementStart(0, "header", 3)(1, "h1", 18), e.ɵɵtext(2), e.ɵɵelementEnd()()), o & 2) {
|
|
250
|
+
const n = e.ɵɵnextContext();
|
|
251
|
+
e.ɵɵadvance(2), e.ɵɵtextInterpolate(n.header);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function oe(o, t) {
|
|
255
|
+
if (o & 1 && (e.ɵɵelementStart(0, "div", 7), e.ɵɵelement(1, "sqg-logo", 19), e.ɵɵelementEnd()), o & 2) {
|
|
256
|
+
let n;
|
|
257
|
+
const i = e.ɵɵnextContext();
|
|
258
|
+
e.ɵɵadvance(), e.ɵɵproperty("isConnected", (i.controller == null || (n = i.controller.state()) == null ? null : n.isConnected) ?? !1);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function ie(o, t) {
|
|
262
|
+
if (o & 1) {
|
|
263
|
+
const n = e.ɵɵgetCurrentView();
|
|
264
|
+
e.ɵɵelementStart(0, "div", 9)(1, "button", 20), e.ɵɵlistener("click", function() {
|
|
265
|
+
e.ɵɵrestoreView(n);
|
|
266
|
+
const s = e.ɵɵnextContext();
|
|
267
|
+
return e.ɵɵresetView(s.retry());
|
|
268
|
+
}), e.ɵɵelement(2, "span", 21), e.ɵɵelementStart(3, "span"), e.ɵɵtext(4, "Reload"), e.ɵɵelementEnd()()();
|
|
269
|
+
}
|
|
270
|
+
if (o & 2) {
|
|
271
|
+
const n = e.ɵɵnextContext();
|
|
272
|
+
e.ɵɵadvance(2), e.ɵɵproperty("innerHTML", n.redoIcon, e.ɵɵsanitizeHtml);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function re(o, t) {
|
|
276
|
+
o & 1 && (e.ɵɵelementStart(0, "div", 9)(1, "p", 22), e.ɵɵtext(2, "Click QR code to reload"), e.ɵɵelementEnd()());
|
|
277
|
+
}
|
|
278
|
+
function se(o, t) {
|
|
279
|
+
if (o & 1 && e.ɵɵelement(0, "sqg-document-previewer", 23), o & 2) {
|
|
280
|
+
const n = t.$implicit;
|
|
281
|
+
e.ɵɵproperty("file", n);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function ae(o, t) {
|
|
285
|
+
if (o & 1 && e.ɵɵrepeaterCreate(0, se, 1, 1, "sqg-document-previewer", 23, Z), o & 2) {
|
|
286
|
+
let n;
|
|
287
|
+
const i = e.ɵɵnextContext();
|
|
288
|
+
e.ɵɵrepeater((i.controller == null || (n = i.controller.state()) == null ? null : n.uploadedFiles) ?? e.ɵɵpureFunction0(0, T));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function le(o, t) {
|
|
292
|
+
if (o & 1 && e.ɵɵelement(0, "sqg-file-list", 11), o & 2) {
|
|
293
|
+
let n;
|
|
294
|
+
const i = e.ɵɵnextContext();
|
|
295
|
+
e.ɵɵproperty("files", (i.controller == null || (n = i.controller.state()) == null ? null : n.uploadedFiles) ?? e.ɵɵpureFunction0(1, T));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
const m = class m {
|
|
299
|
+
constructor(t, n) {
|
|
300
|
+
this.sanitizer = t, this.injector = n, this.showHeader = !1, this.header = "", this.showLogo = !0, this.clickQrCodeToReload = !1, this.filePreviewMode = "grid", this.size = "large", this.qrSvg = q(""), this.redoIcon = t.bypassSecurityTrustHtml(U);
|
|
301
|
+
}
|
|
302
|
+
ngOnInit() {
|
|
303
|
+
this.controller = X({
|
|
304
|
+
sessionUrl: this.sessionUrl,
|
|
305
|
+
refreshTokenUrl: this.refreshTokenUrl
|
|
306
|
+
}), this.controller.start(), S(() => {
|
|
307
|
+
const t = this.controller?.state().deviceLoginUrl || "http://localhost";
|
|
308
|
+
Y(t, 200).then((n) => this.qrSvg.set(this.sanitizer.bypassSecurityTrustHtml(n))).catch(() => {
|
|
309
|
+
});
|
|
310
|
+
}, { injector: this.injector });
|
|
311
|
+
}
|
|
312
|
+
ngOnChanges(t) {
|
|
313
|
+
this.controller && (t.sessionUrl || t.refreshTokenUrl) && this.controller.setOptions({
|
|
314
|
+
sessionUrl: this.sessionUrl,
|
|
315
|
+
refreshTokenUrl: this.refreshTokenUrl
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
ngOnDestroy() {
|
|
319
|
+
this.controller?.dispose();
|
|
320
|
+
}
|
|
321
|
+
async retry() {
|
|
322
|
+
await this.controller?.retrySession();
|
|
323
|
+
}
|
|
324
|
+
async onQrClick() {
|
|
325
|
+
this.clickQrCodeToReload && await this.controller?.retrySession();
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
m.ɵfac = function(n) {
|
|
329
|
+
return new (n || m)(e.ɵɵdirectiveInject(u.DomSanitizer), e.ɵɵdirectiveInject(e.Injector));
|
|
330
|
+
}, m.ɵcmp = /* @__PURE__ */ e.ɵɵdefineComponent({ type: m, selectors: [["sqg-qr-code-generator"]], inputs: { sessionUrl: "sessionUrl", refreshTokenUrl: "refreshTokenUrl", showHeader: "showHeader", header: "header", showLogo: "showLogo", clickQrCodeToReload: "clickQrCodeToReload", filePreviewMode: "filePreviewMode", size: "size" }, features: [e.ɵɵNgOnChangesFeature], decls: 16, vars: 11, consts: [[1, "sqg-root"], [1, "sqg-overlay"], [1, "sqg-content"], [1, "sqg-header"], ["aria-label", "QR Code for file upload", 1, "sqg-qr-wrapper", 3, "click"], [1, "sqg-qr-inner"], [1, "sqg-qr-svg", 3, "innerHTML"], [1, "sqg-logo-overlay"], [1, "sqg-sr-only"], [1, "sqg-reload-section"], [1, "sqg-file-container"], [3, "files"], [1, "sqg-loading-content"], [1, "sqg-spinner"], [1, "sqg-loading-text"], [1, "sqg-error-content"], [1, "sqg-error-text"], [1, "sqg-retry-btn", 3, "click", "innerHTML"], [1, "sqg-header-title"], [3, "isConnected"], [1, "sqg-reload-btn", 3, "click"], [3, "innerHTML"], [1, "sqg-hint-text"], [3, "file"]], template: function(n, i) {
|
|
331
|
+
if (n & 1 && (e.ɵɵelementStart(0, "section", 0), e.ɵɵconditionalCreate(1, ee, 5, 0, "div", 1), e.ɵɵconditionalCreate(2, te, 5, 1, "div", 1), e.ɵɵelementStart(3, "div", 2), e.ɵɵconditionalCreate(4, ne, 3, 1, "header", 3), e.ɵɵelementStart(5, "div", 4), e.ɵɵlistener("click", function() {
|
|
332
|
+
return i.onQrClick();
|
|
333
|
+
}), e.ɵɵelementStart(6, "div", 5), e.ɵɵelement(7, "div", 6), e.ɵɵconditionalCreate(8, oe, 2, 1, "div", 7), e.ɵɵelementEnd(), e.ɵɵelementStart(9, "p", 8), e.ɵɵtext(10), e.ɵɵelementEnd()(), e.ɵɵconditionalCreate(11, ie, 5, 1, "div", 9)(12, re, 3, 0, "div", 9), e.ɵɵelementStart(13, "div", 10), e.ɵɵconditionalCreate(14, ae, 2, 1)(15, le, 1, 2, "sqg-file-list", 11), e.ɵɵelementEnd()()()), n & 2) {
|
|
334
|
+
let s;
|
|
335
|
+
e.ɵɵattribute("data-size", i.size), e.ɵɵadvance(), e.ɵɵconditional(i.controller && i.controller.state().loading ? 1 : -1), e.ɵɵadvance(), e.ɵɵconditional(i.controller && !i.controller.state().loading && i.controller.state().retry ? 2 : -1), e.ɵɵadvance(2), e.ɵɵconditional(i.showHeader ? 4 : -1), e.ɵɵadvance(), e.ɵɵstyleProp("cursor", i.clickQrCodeToReload ? "pointer" : null), e.ɵɵadvance(2), e.ɵɵproperty("innerHTML", i.qrSvg(), e.ɵɵsanitizeHtml), e.ɵɵadvance(), e.ɵɵconditional(i.showLogo ? 8 : -1), e.ɵɵadvance(2), e.ɵɵtextInterpolate1("QR Code that allows uploads from ", i.controller == null || (s = i.controller.state()) == null ? null : s.deviceLoginUrl), e.ɵɵadvance(), e.ɵɵconditional(i.clickQrCodeToReload ? 12 : 11), e.ɵɵadvance(3), e.ɵɵconditional(i.filePreviewMode === "grid" ? 14 : 15);
|
|
336
|
+
}
|
|
337
|
+
}, dependencies: [g, f, C], encapsulation: 2, changeDetection: 0 });
|
|
338
|
+
let w = m;
|
|
339
|
+
export {
|
|
340
|
+
f as DocumentPreviewerComponent,
|
|
341
|
+
C as FileListComponent,
|
|
342
|
+
g as LogoComponent,
|
|
343
|
+
h as ProgressBarComponent,
|
|
344
|
+
w as QrCodeGeneratorComponent,
|
|
345
|
+
X as useQrCodeCore
|
|
346
|
+
};
|
|
347
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/icons.ts","../src/components/logo.component.ts","../src/file-icons.ts","../src/components/progress-bar.component.ts","../src/components/document-previewer.component.ts","../src/components/file-list.component.ts","../src/use-qr-code-core.ts","../src/qrcode.ts","../src/qr-code-generator.component.ts"],"sourcesContent":["export const REDO_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 512 512\" fill=\"currentColor\"><path d=\"M500.33 0h-47.41a12 12 0 0 0-12 12.57l4 82.02A247.42 247.42 0 0 0 256 8C119.34 8 8 119.34 8 256s111.34 248 248 248 248-111.34 248-248c0-36.27-7.8-70.75-21.83-101.78a12 12 0 0 0-22.09 9.35A207.59 207.59 0 0 1 464 256c0 114.69-93.31 208-208 208S48 370.69 48 256 141.31 48 256 48a207.45 207.45 0 0 1 155.7 70.28l-94.27-4.49A12 12 0 0 0 316.86 126v47.41a12 12 0 0 0 12 12h171.47a12 12 0 0 0 12-12V12.57A12 12 0 0 0 500.33 0z\"/></svg>`;\n\nexport const QR_SCANNER_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9.5 6.5v3h-3v-3h3M11 5H5v6h6V5zm-1.5 9.5v3h-3v-3h3M11 13H5v6h6v-6zm6.5-6.5v3h-3v-3h3M19 5h-6v6h6V5zm-6 8h1.5v1.5H13V13zm1.5 1.5H16V16h-1.5v-1.5zM16 13h1.5v1.5H16V13zm-3 3h1.5v1.5H13V16zm1.5 1.5H16V19h-1.5v-1.5zM16 16h1.5v1.5H16V16zm1.5-1.5H19V16h-1.5v-1.5zm0 3H19V19h-1.5v-1.5zM22 7h-2V4h-3V2h5v5zm0 15v-5h-2v3h-3v2h5zM2 22h5v-2H4v-3H2v5zM2 2v5h2V4h3V2H2z\"/></svg>`;\n\nexport const REMOVE_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"m15 9-6 6\"/><path d=\"m9 9 6 6\"/></svg>`;\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\nimport { QR_SCANNER_SVG } from '../icons';\n\n@Component({\n selector: 'sqg-logo',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<span [class]=\"cssClass\" [innerHTML]=\"svg\"></span>`\n})\nexport class LogoComponent {\n @Input() isConnected = false;\n\n protected readonly svg: SafeHtml;\n\n constructor(sanitizer: DomSanitizer) {\n this.svg = sanitizer.bypassSecurityTrustHtml(QR_SCANNER_SVG);\n }\n\n protected get cssClass(): string {\n return this.isConnected ? 'sqg-logo sqg-logo--connected' : 'sqg-logo sqg-logo--disconnected';\n }\n}\n","import {\n createElement,\n File,\n FileText,\n FileImage,\n FileVideo,\n FileAudio,\n FileArchive,\n FileCode,\n FileSpreadsheet,\n FileType,\n FileDigit,\n FileJson,\n Presentation,\n type IconNode\n} from 'lucide';\n\n/**\n * Create an SVG string from a Lucide icon node with the given size and color.\n */\nfunction renderIcon(icon: IconNode, size: number, color: string): string {\n const el = createElement(icon);\n el.setAttribute('width', String(size));\n el.setAttribute('height', String(size));\n el.setAttribute('stroke', color);\n return el.outerHTML;\n}\n\n/**\n * Returns an inline SVG string for a file-type icon based on the extension.\n * Uses the same Lucide icons and colour mapping as the React DocumentPreviewer.\n */\nexport function getFileIconSvg(extension: string, size = 24): string {\n const ext = extension.toLowerCase();\n\n switch (ext) {\n // Documents\n case 'pdf':\n return renderIcon(File, size, '#ef4444');\n case 'doc':\n case 'docx':\n return renderIcon(FileText, size, '#3b82f6');\n case 'xls':\n case 'xlsx':\n return renderIcon(FileSpreadsheet, size, '#16a34a');\n case 'csv':\n return renderIcon(FileSpreadsheet, size, '#22c55e');\n case 'ppt':\n case 'pptx':\n return renderIcon(Presentation, size, '#f97316');\n case 'txt':\n case 'rtf':\n return renderIcon(FileText, size, '#4b5563');\n case 'md':\n return renderIcon(FileDigit, size, '#4b5563');\n\n // Images\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'svg':\n case 'bmp':\n case 'webp':\n case 'ico':\n return renderIcon(FileImage, size, '#a855f7');\n\n // Video\n case 'mp4':\n case 'avi':\n case 'mov':\n case 'wmv':\n case 'flv':\n case 'webm':\n case 'mkv':\n return renderIcon(FileVideo, size, '#9333ea');\n\n // Audio\n case 'mp3':\n case 'wav':\n case 'ogg':\n case 'flac':\n case 'm4a':\n case 'aac':\n return renderIcon(FileAudio, size, '#ec4899');\n\n // Archives\n case 'zip':\n case 'rar':\n case '7z':\n case 'tar':\n case 'gz':\n case 'bz2':\n return renderIcon(FileArchive, size, '#ca8a04');\n\n // Code\n case 'js':\n case 'jsx':\n return renderIcon(FileCode, size, '#eab308');\n case 'ts':\n case 'tsx':\n return renderIcon(FileType, size, '#2563eb');\n case 'html':\n case 'htm':\n return renderIcon(FileCode, size, '#ea580c');\n case 'css':\n return renderIcon(FileCode, size, '#60a5fa');\n case 'json':\n return renderIcon(FileJson, size, '#374151');\n case 'xml':\n case 'yml':\n case 'yaml':\n return renderIcon(FileCode, size, '#4b5563');\n\n default:\n return renderIcon(File, size, '#6b7280');\n }\n}\n\n/** Generic document icon for list-view when no thumbnail is available. */\nexport function getGenericDocIconSvg(size = 24): string {\n return renderIcon(File, size, '#6b7280');\n}\n\n/** Extract the lowercase file extension from a file name. */\nexport function getFileExtension(filename: string): string {\n const parts = filename.split('.');\n return parts.length > 1 ? parts.pop()!.toLowerCase() : '';\n}\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'sqg-progress-bar',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"sqg-progress-wrap\">\n <div class=\"sqg-progress-labels\">\n <span class=\"sqg-progress-label\">Uploading...</span>\n <span class=\"sqg-progress-label\">{{ rounded }}%</span>\n </div>\n <div class=\"sqg-progress-track\">\n <div class=\"sqg-progress-fill\" [style.width.%]=\"progress || 0\"></div>\n </div>\n </div>\n `\n})\nexport class ProgressBarComponent {\n @Input() progress = 0;\n\n protected get rounded(): number {\n return Math.round(this.progress || 0);\n }\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\nimport type { UploadedFile } from '@scanupload/qr-code-generator-core';\nimport { getFileExtension, getFileIconSvg } from '../file-icons';\nimport { REMOVE_SVG } from '../icons';\nimport { ProgressBarComponent } from './progress-bar.component';\n\n@Component({\n selector: 'sqg-document-previewer',\n standalone: true,\n imports: [ProgressBarComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"sqg-file-card\">\n <div class=\"sqg-file-inner\">\n @if (file.thumbnailBase64) {\n <div class=\"sqg-thumb-wrap\">\n <img [src]=\"'data:' + file.type + ';base64,' + file.thumbnailBase64\" class=\"sqg-thumb-img\" [alt]=\"file.name\" />\n </div>\n } @else {\n <div class=\"sqg-icon-wrap\" [attr.data-filetype]=\"extension\" [innerHTML]=\"iconSvg\"></div>\n @if (showExtension && extension) {\n <div class=\"sqg-ext-badge\">\n <span>{{ extension.toUpperCase() }}</span>\n </div>\n }\n }\n <div class=\"sqg-file-info\">\n <div class=\"sqg-file-meta\">\n <p class=\"sqg-file-name\" [title]=\"file.name\">{{ file.name }}</p>\n <p class=\"sqg-file-size\">({{ (file.size / 1024).toFixed(1) }} KB)</p>\n </div>\n @if (showRemoveButton) {\n <button\n class=\"sqg-remove-btn\"\n aria-label=\"Remove File\"\n [innerHTML]=\"removeIcon\"\n (click)=\"removeFile.emit(file.id)\"\n ></button>\n }\n </div>\n <sqg-progress-bar [progress]=\"file.progress\"></sqg-progress-bar>\n </div>\n </div>\n `\n})\nexport class DocumentPreviewerComponent {\n @Input({ required: true }) file!: UploadedFile;\n @Input() showExtension = true;\n @Input() showRemoveButton = false;\n @Output() removeFile = new EventEmitter<string>();\n\n protected readonly removeIcon: SafeHtml;\n\n constructor(private readonly sanitizer: DomSanitizer) {\n this.removeIcon = sanitizer.bypassSecurityTrustHtml(REMOVE_SVG);\n }\n\n protected get extension(): string {\n return getFileExtension(this.file.name);\n }\n\n protected get iconSvg(): SafeHtml {\n return this.sanitizer.bypassSecurityTrustHtml(getFileIconSvg(this.extension, 40));\n }\n}\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\nimport type { UploadedFile } from '@scanupload/qr-code-generator-core';\nimport { getGenericDocIconSvg } from '../file-icons';\n\n@Component({\n selector: 'sqg-file-list',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"sqg-file-list\">\n <div class=\"sqg-file-list-inner\">\n @for (file of files; track file.id) {\n <div class=\"sqg-file-row\">\n <div class=\"sqg-list-thumb\">\n @if (file.thumbnailBase64) {\n <img [src]=\"'data:' + file.type + ';base64,' + file.thumbnailBase64\" [alt]=\"file.name\" />\n } @else {\n <span [innerHTML]=\"docIcon\"></span>\n }\n </div>\n <div class=\"sqg-list-info\">\n <span class=\"sqg-list-name\" [title]=\"file.name\">{{ file.name }}</span>\n <span class=\"sqg-list-size\">{{ (file.size / 1024).toFixed(1) }} KB</span>\n </div>\n </div>\n }\n </div>\n </div>\n `\n})\nexport class FileListComponent {\n @Input() files: UploadedFile[] = [];\n\n protected readonly docIcon: SafeHtml;\n\n constructor(sanitizer: DomSanitizer) {\n this.docIcon = sanitizer.bypassSecurityTrustHtml(getGenericDocIconSvg(24));\n }\n}\n","import { signal, type Signal } from '@angular/core';\nimport { QrCodeGeneratorCore } from '@scanupload/qr-code-generator-core';\nimport type { QrCodeGeneratorState, StorageAdapter } from '@scanupload/qr-code-generator-core';\n\nexport interface UseQrCodeCoreOptions {\n sessionUrl: string;\n refreshTokenUrl: string;\n storage?: StorageAdapter;\n}\n\nexport interface QrCodeCoreController {\n /** Reactive snapshot of the core state. */\n state: Signal<QrCodeGeneratorState>;\n /** Subscribe to the core and start the live session. */\n start(): void;\n /** Tear down the current session and create a new one. */\n retrySession(): Promise<void>;\n /** Update the API endpoints at runtime (mirrors the core `setOptions`). */\n setOptions(opts: { sessionUrl?: string; refreshTokenUrl?: string }): Promise<void>;\n /** Unsubscribe and dispose the underlying core. */\n dispose(): void;\n}\n\n/**\n * Signal-based controller that wraps {@link QrCodeGeneratorCore}, mirroring the\n * React `useQrCodeCore` hook and the Vue `useQrCodeCore` composable.\n *\n * Instantiate it once the component inputs are available (e.g. in `ngOnInit`),\n * call `start()`, and `dispose()` on destroy.\n */\nexport function useQrCodeCore(options: UseQrCodeCoreOptions): QrCodeCoreController {\n const core = new QrCodeGeneratorCore({\n sessionUrl: options.sessionUrl,\n refreshTokenUrl: options.refreshTokenUrl,\n storage: options.storage\n });\n\n const state = signal<QrCodeGeneratorState>(core.getState());\n\n let unsubscribe: (() => void) | null = null;\n\n return {\n state: state.asReadonly(),\n start() {\n unsubscribe = core.subscribe(() => state.set(core.getState()));\n state.set(core.getState());\n void core.start();\n },\n retrySession: () => core.retrySession(),\n setOptions: (opts) => core.setOptions(opts),\n dispose() {\n unsubscribe?.();\n unsubscribe = null;\n core.dispose();\n }\n };\n}\n","import QRCode from 'qrcode';\n\n/**\n * Generate a QR code as an SVG string using the `qrcode` library.\n * Returns a placeholder SVG when `text` is falsy.\n */\nexport async function generateQrSvg(text: string, size = 200): Promise<string> {\n return QRCode.toString(text || 'http://localhost', {\n type: 'svg',\n width: size,\n margin: 2,\n errorCorrectionLevel: 'L'\n });\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n effect,\n Injector,\n Input,\n OnChanges,\n OnDestroy,\n OnInit,\n signal,\n SimpleChanges\n} from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\nimport { LogoComponent } from './components/logo.component';\nimport { DocumentPreviewerComponent } from './components/document-previewer.component';\nimport { FileListComponent } from './components/file-list.component';\nimport { useQrCodeCore, type QrCodeCoreController } from './use-qr-code-core';\nimport { generateQrSvg } from './qrcode';\nimport { REDO_SVG } from './icons';\n\nexport type FilePreviewMode = 'list' | 'grid';\nexport type QrCodeSize = 'small' | 'medium' | 'large' | 'xlarge';\n\n@Component({\n selector: 'sqg-qr-code-generator',\n standalone: true,\n imports: [LogoComponent, DocumentPreviewerComponent, FileListComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <section class=\"sqg-root\" [attr.data-size]=\"size\">\n @if (controller && controller.state().loading) {\n <div class=\"sqg-overlay\">\n <div class=\"sqg-loading-content\">\n <div class=\"sqg-spinner\"></div>\n <p class=\"sqg-loading-text\">Loading...</p>\n </div>\n </div>\n }\n @if (controller && !controller.state().loading && controller.state().retry) {\n <div class=\"sqg-overlay\">\n <div class=\"sqg-error-content\">\n <p class=\"sqg-error-text\">Cannot create session</p>\n <button class=\"sqg-retry-btn\" [innerHTML]=\"redoIcon\" (click)=\"retry()\"></button>\n </div>\n </div>\n }\n <div class=\"sqg-content\">\n @if (showHeader) {\n <header class=\"sqg-header\">\n <h1 class=\"sqg-header-title\">{{ header }}</h1>\n </header>\n }\n <div\n aria-label=\"QR Code for file upload\"\n class=\"sqg-qr-wrapper\"\n [style.cursor]=\"clickQrCodeToReload ? 'pointer' : null\"\n (click)=\"onQrClick()\"\n >\n <div class=\"sqg-qr-inner\">\n <div class=\"sqg-qr-svg\" [innerHTML]=\"qrSvg()\"></div>\n @if (showLogo) {\n <div class=\"sqg-logo-overlay\">\n <sqg-logo [isConnected]=\"controller?.state()?.isConnected ?? false\"></sqg-logo>\n </div>\n }\n </div>\n <p class=\"sqg-sr-only\">QR Code that allows uploads from {{ controller?.state()?.deviceLoginUrl }}</p>\n </div>\n @if (!clickQrCodeToReload) {\n <div class=\"sqg-reload-section\">\n <button class=\"sqg-reload-btn\" (click)=\"retry()\"><span [innerHTML]=\"redoIcon\"></span> <span>Reload</span></button>\n </div>\n } @else {\n <div class=\"sqg-reload-section\">\n <p class=\"sqg-hint-text\">Click QR code to reload</p>\n </div>\n }\n <div class=\"sqg-file-container\">\n @if (filePreviewMode === 'grid') {\n @for (file of controller?.state()?.uploadedFiles ?? []; track file.id) {\n <sqg-document-previewer [file]=\"file\"></sqg-document-previewer>\n }\n } @else {\n <sqg-file-list [files]=\"controller?.state()?.uploadedFiles ?? []\"></sqg-file-list>\n }\n </div>\n </div>\n </section>\n `\n})\nexport class QrCodeGeneratorComponent implements OnInit, OnChanges, OnDestroy {\n @Input({ required: true }) sessionUrl!: string;\n @Input({ required: true }) refreshTokenUrl!: string;\n @Input() showHeader = false;\n @Input() header = '';\n @Input() showLogo = true;\n @Input() clickQrCodeToReload = false;\n @Input() filePreviewMode: FilePreviewMode = 'grid';\n @Input() size: QrCodeSize = 'large';\n\n protected controller?: QrCodeCoreController;\n protected readonly qrSvg = signal<SafeHtml>('');\n protected readonly redoIcon: SafeHtml;\n\n constructor(\n private readonly sanitizer: DomSanitizer,\n private readonly injector: Injector\n ) {\n this.redoIcon = sanitizer.bypassSecurityTrustHtml(REDO_SVG);\n }\n\n ngOnInit(): void {\n this.controller = useQrCodeCore({\n sessionUrl: this.sessionUrl,\n refreshTokenUrl: this.refreshTokenUrl\n });\n this.controller.start();\n\n // Regenerate the QR SVG whenever the device login URL changes.\n effect(\n () => {\n const url = this.controller?.state().deviceLoginUrl || 'http://localhost';\n generateQrSvg(url, 200)\n .then((svg) => this.qrSvg.set(this.sanitizer.bypassSecurityTrustHtml(svg)))\n .catch(() => undefined);\n },\n { injector: this.injector }\n );\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (this.controller && (changes['sessionUrl'] || changes['refreshTokenUrl'])) {\n void this.controller.setOptions({\n sessionUrl: this.sessionUrl,\n refreshTokenUrl: this.refreshTokenUrl\n });\n }\n }\n\n ngOnDestroy(): void {\n this.controller?.dispose();\n }\n\n protected async retry(): Promise<void> {\n await this.controller?.retrySession();\n }\n\n protected async onQrClick(): Promise<void> {\n if (this.clickQrCodeToReload) {\n await this.controller?.retrySession();\n }\n }\n}\n"],"names":["REDO_SVG","QR_SCANNER_SVG","REMOVE_SVG","__ngFactoryType__","_LogoComponent","i0","i1","rf","ctx","renderIcon","icon","size","color","el","createElement","getFileIconSvg","extension","File","FileText","FileSpreadsheet","Presentation","FileDigit","FileImage","FileVideo","FileAudio","FileArchive","FileCode","FileType","FileJson","getGenericDocIconSvg","getFileExtension","filename","parts","_ProgressBarComponent","ctx_r0","DocumentPreviewerComponent_Conditional_3_Conditional_1_Template","DocumentPreviewerComponent_Conditional_3_Template","DocumentPreviewerComponent_Conditional_10_Template","_r2","_DocumentPreviewerComponent","sanitizer","EventEmitter","DocumentPreviewerComponent_Conditional_2_Template","DocumentPreviewerComponent","file_r1","FileListComponent_For_3_Conditional_3_Template","ctx_r1","FileListComponent_For_3_Template","FileListComponent_For_3_Conditional_2_Template","_FileListComponent","_forTrack0","FileListComponent","useQrCodeCore","options","core","QrCodeGeneratorCore","state","signal","unsubscribe","opts","generateQrSvg","text","QRCode","_c0","$index","$item","QrCodeGeneratorComponent_Conditional_1_Template","QrCodeGeneratorComponent_Conditional_2_Template","_r1","QrCodeGeneratorComponent_Conditional_4_Template","QrCodeGeneratorComponent_Conditional_8_Template","tmp_1_0","_r3","QrCodeGeneratorComponent_Conditional_12_Template","QrCodeGeneratorComponent_Conditional_14_For_1_Template","file_r4","QrCodeGeneratorComponent_Conditional_14_Template","QrCodeGeneratorComponent_Conditional_15_Template","_QrCodeGeneratorComponent","injector","effect","url","svg","changes","QrCodeGeneratorComponent_Conditional_11_Template","tmp_7_0","QrCodeGeneratorComponent"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Injector, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { DomSanitizer, type SafeHtml } from '@angular/platform-browser';
|
|
3
|
+
import { type QrCodeCoreController } from './use-qr-code-core';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export type FilePreviewMode = 'list' | 'grid';
|
|
6
|
+
export type QrCodeSize = 'small' | 'medium' | 'large' | 'xlarge';
|
|
7
|
+
export declare class QrCodeGeneratorComponent implements OnInit, OnChanges, OnDestroy {
|
|
8
|
+
private readonly sanitizer;
|
|
9
|
+
private readonly injector;
|
|
10
|
+
sessionUrl: string;
|
|
11
|
+
refreshTokenUrl: string;
|
|
12
|
+
showHeader: boolean;
|
|
13
|
+
header: string;
|
|
14
|
+
showLogo: boolean;
|
|
15
|
+
clickQrCodeToReload: boolean;
|
|
16
|
+
filePreviewMode: FilePreviewMode;
|
|
17
|
+
size: QrCodeSize;
|
|
18
|
+
protected controller?: QrCodeCoreController;
|
|
19
|
+
protected readonly qrSvg: import("@angular/core").WritableSignal<SafeHtml>;
|
|
20
|
+
protected readonly redoIcon: SafeHtml;
|
|
21
|
+
constructor(sanitizer: DomSanitizer, injector: Injector);
|
|
22
|
+
ngOnInit(): void;
|
|
23
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
24
|
+
ngOnDestroy(): void;
|
|
25
|
+
protected retry(): Promise<void>;
|
|
26
|
+
protected onQrClick(): Promise<void>;
|
|
27
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<QrCodeGeneratorComponent, never>;
|
|
28
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<QrCodeGeneratorComponent, "sqg-qr-code-generator", never, { "sessionUrl": { "alias": "sessionUrl"; "required": true; }; "refreshTokenUrl": { "alias": "refreshTokenUrl"; "required": true; }; "showHeader": { "alias": "showHeader"; "required": false; }; "header": { "alias": "header"; "required": false; }; "showLogo": { "alias": "showLogo"; "required": false; }; "clickQrCodeToReload": { "alias": "clickQrCodeToReload"; "required": false; }; "filePreviewMode": { "alias": "filePreviewMode"; "required": false; }; "size": { "alias": "size"; "required": false; }; }, {}, never, never, true, never>;
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr-code-generator.component.d.ts","sourceRoot":"","sources":["../src/qr-code-generator.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,QAAQ,EAER,SAAS,EACT,SAAS,EACT,MAAM,EAEN,aAAa,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAIxE,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAI9E,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,CAAC;AAC9C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjE,qBAmEa,wBAAyB,YAAW,MAAM,EAAE,SAAS,EAAE,SAAS;IAerE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAfF,UAAU,EAAG,MAAM,CAAC;IACpB,eAAe,EAAG,MAAM,CAAC;IAC3C,UAAU,UAAS;IACnB,MAAM,SAAM;IACZ,QAAQ,UAAQ;IAChB,mBAAmB,UAAS;IAC5B,eAAe,EAAE,eAAe,CAAU;IAC1C,IAAI,EAAE,UAAU,CAAW;IAEpC,SAAS,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,KAAK,mDAAwB;IAChD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAGjB,SAAS,EAAE,YAAY,EACvB,QAAQ,EAAE,QAAQ;IAKvC,QAAQ,IAAI,IAAI;IAmBhB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IASzC,WAAW,IAAI,IAAI;cAIH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;cAItB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7C"}
|
package/dist/qrcode.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qrcode.d.ts","sourceRoot":"","sources":["../src/qrcode.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Signal } from '@angular/core';
|
|
2
|
+
import type { QrCodeGeneratorState, StorageAdapter } from '@scanupload/qr-code-generator-core';
|
|
3
|
+
export interface UseQrCodeCoreOptions {
|
|
4
|
+
sessionUrl: string;
|
|
5
|
+
refreshTokenUrl: string;
|
|
6
|
+
storage?: StorageAdapter;
|
|
7
|
+
}
|
|
8
|
+
export interface QrCodeCoreController {
|
|
9
|
+
/** Reactive snapshot of the core state. */
|
|
10
|
+
state: Signal<QrCodeGeneratorState>;
|
|
11
|
+
/** Subscribe to the core and start the live session. */
|
|
12
|
+
start(): void;
|
|
13
|
+
/** Tear down the current session and create a new one. */
|
|
14
|
+
retrySession(): Promise<void>;
|
|
15
|
+
/** Update the API endpoints at runtime (mirrors the core `setOptions`). */
|
|
16
|
+
setOptions(opts: {
|
|
17
|
+
sessionUrl?: string;
|
|
18
|
+
refreshTokenUrl?: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
/** Unsubscribe and dispose the underlying core. */
|
|
21
|
+
dispose(): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Signal-based controller that wraps {@link QrCodeGeneratorCore}, mirroring the
|
|
25
|
+
* React `useQrCodeCore` hook and the Vue `useQrCodeCore` composable.
|
|
26
|
+
*
|
|
27
|
+
* Instantiate it once the component inputs are available (e.g. in `ngOnInit`),
|
|
28
|
+
* call `start()`, and `dispose()` on destroy.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useQrCodeCore(options: UseQrCodeCoreOptions): QrCodeCoreController;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-qr-code-core.d.ts","sourceRoot":"","sources":["../src/use-qr-code-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAE/F,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACpC,wDAAwD;IACxD,KAAK,IAAI,IAAI,CAAC;IACd,0DAA0D;IAC1D,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,2EAA2E;IAC3E,UAAU,CAAC,IAAI,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnF,mDAAmD;IACnD,OAAO,IAAI,IAAI,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,oBAAoB,CA0BjF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scanupload/qr-code-generator-angular",
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "Angular wrapper for the ScanUpload QR Code Generator — QR code component with real-time file upload previews.",
|
|
5
|
+
"main": "dist/index.es.js",
|
|
6
|
+
"module": "dist/index.es.js",
|
|
7
|
+
"style": "dist/index.css",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "vite build"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"@angular/common": ">=20.2.0",
|
|
17
|
+
"@angular/core": ">=20.2.0"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@scanupload/qr-code-generator-core": "^0.1.9",
|
|
21
|
+
"lucide": "^0.562.0",
|
|
22
|
+
"qrcode": "^1.5.4",
|
|
23
|
+
"tslib": "^2.8.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@analogjs/vite-plugin-angular": "^2.6.1",
|
|
27
|
+
"@angular/build": "^20.3.0",
|
|
28
|
+
"@angular/common": "^20.3.0",
|
|
29
|
+
"@angular/compiler": "^20.3.0",
|
|
30
|
+
"@angular/compiler-cli": "^20.3.0",
|
|
31
|
+
"@angular/core": "^20.3.0",
|
|
32
|
+
"@angular/platform-browser": "^20.3.0",
|
|
33
|
+
"@types/qrcode": "^1.5.5",
|
|
34
|
+
"rxjs": "^7.8.1",
|
|
35
|
+
"typescript": "^5.9.3",
|
|
36
|
+
"vite": "^7.1.11",
|
|
37
|
+
"vite-plugin-dts": "^4.5.4",
|
|
38
|
+
"zone.js": "^0.15.0"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"scanupload",
|
|
42
|
+
"qr-code",
|
|
43
|
+
"angular",
|
|
44
|
+
"signalr"
|
|
45
|
+
],
|
|
46
|
+
"author": "Donald Asante",
|
|
47
|
+
"license": "MIT"
|
|
48
|
+
}
|