@theseam/ui-common 1.0.2-beta.60 → 1.0.2-beta.67

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.
@@ -0,0 +1,190 @@
1
+ import * as _theseam_ui_common_icon from '@theseam/ui-common/icon';
2
+ import { SeamIcon } from '@theseam/ui-common/icon';
3
+ import * as _angular_core from '@angular/core';
4
+ import { AfterViewInit } from '@angular/core';
5
+ import * as _fortawesome_fontawesome_common_types from '@fortawesome/fontawesome-common-types';
6
+ import { ControlValueAccessor } from '@angular/forms';
7
+
8
+ /** Tagged union describing where a file item's bytes (or asset pointer) live. */
9
+ type SeamFileItemSource = {
10
+ kind: 'file';
11
+ file: File;
12
+ } | {
13
+ kind: 'url';
14
+ url: string;
15
+ } | {
16
+ kind: 'blob';
17
+ blob: Blob;
18
+ };
19
+ /**
20
+ * A file entry usable by `<seam-file-tile>` and `<seam-file-field>`.
21
+ *
22
+ * Covers three cases:
23
+ * - Pending upload (File source)
24
+ * - Already-uploaded server asset (URL source)
25
+ * - In-memory bytes without a File wrapper (Blob source)
26
+ */
27
+ interface SeamFileItem {
28
+ /** Display name. */
29
+ name: string;
30
+ /** Bytes. Known for File/Blob; optional for URL. */
31
+ size?: number;
32
+ /** MIME type. Known for File/Blob; may be absent for URL. */
33
+ type?: string;
34
+ /** Where the bytes (or the asset pointer) live. */
35
+ source: SeamFileItemSource;
36
+ /** Consumer-supplied tracking key (e.g. documentId, syncId). */
37
+ id?: string;
38
+ /** Override thumbnail URL. Otherwise derived for image sources. */
39
+ thumbnailUrl?: string;
40
+ }
41
+ /** Why a file was rejected at selection/drop time. */
42
+ type SeamFileRejectionReason = 'type' | 'size' | 'count';
43
+ /** One rejected file and the set of reasons it failed validation. */
44
+ interface SeamFileRejection {
45
+ file: File;
46
+ reasons: SeamFileRejectionReason[];
47
+ }
48
+ /** Tile layout. `row` = horizontal list item; `preview` = thumbnail tile. */
49
+ type SeamFileTileVariant = 'row' | 'preview';
50
+
51
+ declare function seamFileItemFromFile(file: File, id?: string): SeamFileItem;
52
+ interface SeamFileItemFromUrlOptions {
53
+ name?: string;
54
+ type?: string;
55
+ size?: number;
56
+ id?: string;
57
+ thumbnailUrl?: string;
58
+ }
59
+ declare function seamFileItemFromUrl(url: string, opts?: SeamFileItemFromUrlOptions): SeamFileItem;
60
+ /**
61
+ * Extracts native `File` objects from items whose source is `file`. Items
62
+ * backed by a URL or a Blob are ignored. Useful for submit-side mapping
63
+ * when the consumer only cares about newly-uploaded blobs.
64
+ */
65
+ declare function seamFilesFromItems(items: SeamFileItem[]): File[];
66
+ /**
67
+ * Maps a MIME type to a built-in SeamIcon. Returns a generic file icon for
68
+ * unknown, empty, or missing types. Returns SeamIcon (not IconDefinition) so
69
+ * the icon set can change later without a breaking signature change.
70
+ */
71
+ declare function iconForMime(type: string | undefined): SeamIcon;
72
+
73
+ declare class TheSeamFileDropZoneDirective {
74
+ readonly accept: _angular_core.InputSignal<string>;
75
+ readonly maxSize: _angular_core.InputSignal<number | null>;
76
+ readonly maxFiles: _angular_core.InputSignal<number | null>;
77
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
78
+ readonly seamFileDrop: _angular_core.OutputEmitterRef<File[]>;
79
+ readonly seamFileDropRejected: _angular_core.OutputEmitterRef<SeamFileRejection[]>;
80
+ /** Counter-based dragenter/leave tracking to avoid child-element flicker. */
81
+ private readonly _dragDepth;
82
+ protected readonly _isOver: _angular_core.Signal<boolean>;
83
+ protected _onDragEnter(event: DragEvent): void;
84
+ protected _onDragOver(event: DragEvent): void;
85
+ protected _onDragLeave(event: DragEvent): void;
86
+ protected _onDrop(event: DragEvent): void;
87
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TheSeamFileDropZoneDirective, never>;
88
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TheSeamFileDropZoneDirective, "[seamFileDropZone]", never, { "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "seamFileDrop": "seamFileDrop"; "seamFileDropRejected": "seamFileDropRejected"; }, never, never, true, never>;
89
+ }
90
+
91
+ declare class TheSeamFileInputComponent {
92
+ readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
93
+ readonly accept: _angular_core.InputSignal<string>;
94
+ readonly maxSize: _angular_core.InputSignal<number | null>;
95
+ readonly maxFiles: _angular_core.InputSignal<number | null>;
96
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
97
+ readonly hideErrors: _angular_core.InputSignalWithTransform<boolean, unknown>;
98
+ readonly promptText: _angular_core.InputSignal<string>;
99
+ readonly promptSuffix: _angular_core.InputSignal<string>;
100
+ readonly filesAdded: _angular_core.OutputEmitterRef<File[]>;
101
+ readonly rejected: _angular_core.OutputEmitterRef<SeamFileRejection[]>;
102
+ protected readonly _faUpload: _fortawesome_fontawesome_common_types.IconDefinition;
103
+ protected readonly _lastRejections: _angular_core.WritableSignal<SeamFileRejection[]>;
104
+ protected readonly _effectiveMaxFiles: _angular_core.Signal<number | null>;
105
+ protected readonly _errorMessage: _angular_core.Signal<string | null>;
106
+ private readonly _nativeInput;
107
+ _openPicker(): void;
108
+ protected _onFilesDropped(files: File[]): void;
109
+ protected _onRejected(rejections: SeamFileRejection[]): void;
110
+ protected _onNativeChange(event: Event): void;
111
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TheSeamFileInputComponent, never>;
112
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TheSeamFileInputComponent, "seam-file-input", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hideErrors": { "alias": "hideErrors"; "required": false; "isSignal": true; }; "promptText": { "alias": "promptText"; "required": false; "isSignal": true; }; "promptSuffix": { "alias": "promptSuffix"; "required": false; "isSignal": true; }; }, { "filesAdded": "filesAdded"; "rejected": "rejected"; }, never, never, true, never>;
113
+ }
114
+
115
+ declare class TheSeamFileTileComponent implements AfterViewInit {
116
+ private readonly _cdr;
117
+ readonly item: _angular_core.InputSignal<SeamFileItem>;
118
+ readonly variant: _angular_core.InputSignal<SeamFileTileVariant>;
119
+ readonly showName: _angular_core.InputSignalWithTransform<boolean, unknown>;
120
+ readonly showMeta: _angular_core.InputSignalWithTransform<boolean, unknown>;
121
+ readonly removable: _angular_core.InputSignalWithTransform<boolean, unknown>;
122
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
123
+ readonly remove: _angular_core.OutputEmitterRef<SeamFileItem>;
124
+ readonly itemClick: _angular_core.OutputEmitterRef<SeamFileItem>;
125
+ protected readonly _faTimes: _fortawesome_fontawesome_common_types.IconDefinition;
126
+ protected readonly _mimeIcon: _angular_core.Signal<_theseam_ui_common_icon.SeamIcon>;
127
+ protected readonly _metaLine: _angular_core.Signal<string>;
128
+ protected readonly _showRemoveBtn: _angular_core.Signal<boolean>;
129
+ /** True when itemClick is observed AND the tile is not disabled. */
130
+ protected readonly _isInteractive: _angular_core.Signal<boolean>;
131
+ /**
132
+ * Thumbnail URL for image items. Tracked across item changes so object
133
+ * URLs are revoked when the item changes or the component is destroyed.
134
+ */
135
+ private _ownedObjectUrl;
136
+ private _pendingObjectUrl;
137
+ protected readonly _thumbUrl: _angular_core.Signal<string | null>;
138
+ /**
139
+ * True once we detect that a consumer has wired (itemClick).
140
+ * Detected in ngAfterViewInit — by that point the parent's template binding
141
+ * has called subscribe() on the OutputEmitterRef, populating its internal
142
+ * `listeners` array (Option A: access via internal field on Angular 20's
143
+ * OutputEmitterRef). If the internal shape is absent, conservatively stays
144
+ * false (opt-out default — no unwanted role=button on inert tiles).
145
+ */
146
+ protected readonly _clickObserved: _angular_core.WritableSignal<boolean>;
147
+ constructor();
148
+ ngAfterViewInit(): void;
149
+ protected _onRemove(event: MouseEvent): void;
150
+ protected _onBodyClick(): void;
151
+ protected _onBodyKey(event: KeyboardEvent): void;
152
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TheSeamFileTileComponent, never>;
153
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TheSeamFileTileComponent, "seam-file-tile", never, { "item": { "alias": "item"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "showName": { "alias": "showName"; "required": false; "isSignal": true; }; "showMeta": { "alias": "showMeta"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "remove": "remove"; "itemClick": "itemClick"; }, never, never, true, never>;
154
+ }
155
+
156
+ declare class TheSeamFileFieldComponent implements ControlValueAccessor {
157
+ readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
158
+ readonly accept: _angular_core.InputSignal<string>;
159
+ readonly maxSize: _angular_core.InputSignal<number | null>;
160
+ readonly maxFiles: _angular_core.InputSignal<number | null>;
161
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
162
+ readonly previewMode: _angular_core.InputSignalWithTransform<boolean, unknown>;
163
+ readonly showTileName: _angular_core.InputSignalWithTransform<boolean, unknown>;
164
+ readonly promptText: _angular_core.InputSignal<string>;
165
+ readonly promptSuffix: _angular_core.InputSignal<string>;
166
+ readonly replaceText: _angular_core.InputSignal<string>;
167
+ readonly hideErrors: _angular_core.InputSignalWithTransform<boolean, unknown>;
168
+ readonly rejected: _angular_core.OutputEmitterRef<SeamFileRejection[]>;
169
+ protected readonly _items: _angular_core.WritableSignal<SeamFileItem[]>;
170
+ protected readonly _cvaDisabled: _angular_core.WritableSignal<boolean>;
171
+ protected readonly _effectiveDisabled: _angular_core.Signal<boolean>;
172
+ protected readonly _hasFile: _angular_core.Signal<boolean>;
173
+ protected readonly _remainingMaxFiles: _angular_core.Signal<number | null>;
174
+ protected readonly _tileVariant: _angular_core.Signal<"row" | "preview">;
175
+ private _onChange;
176
+ private _onTouched;
177
+ writeValue(value: SeamFileItem[] | null): void;
178
+ registerOnChange(fn: (value: SeamFileItem[]) => void): void;
179
+ registerOnTouched(fn: () => void): void;
180
+ setDisabledState(isDisabled: boolean): void;
181
+ protected _onFilesAdded(files: File[]): void;
182
+ protected _onRejected(rejections: SeamFileRejection[]): void;
183
+ protected _onTileRemove(item: SeamFileItem): void;
184
+ private _emit;
185
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TheSeamFileFieldComponent, never>;
186
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TheSeamFileFieldComponent, "seam-file-field", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "previewMode": { "alias": "previewMode"; "required": false; "isSignal": true; }; "showTileName": { "alias": "showTileName"; "required": false; "isSignal": true; }; "promptText": { "alias": "promptText"; "required": false; "isSignal": true; }; "promptSuffix": { "alias": "promptSuffix"; "required": false; "isSignal": true; }; "replaceText": { "alias": "replaceText"; "required": false; "isSignal": true; }; "hideErrors": { "alias": "hideErrors"; "required": false; "isSignal": true; }; }, { "rejected": "rejected"; }, never, never, true, never>;
187
+ }
188
+
189
+ export { TheSeamFileDropZoneDirective, TheSeamFileFieldComponent, TheSeamFileInputComponent, TheSeamFileTileComponent, iconForMime, seamFileItemFromFile, seamFileItemFromUrl, seamFilesFromItems };
190
+ export type { SeamFileItem, SeamFileItemFromUrlOptions, SeamFileItemSource, SeamFileRejection, SeamFileRejectionReason, SeamFileTileVariant };
@@ -0,0 +1,3 @@
1
+ {
2
+ "module": "../fesm2022/theseam-ui-common-file-input.mjs"
3
+ }
@@ -5,23 +5,39 @@
5
5
 
6
6
  /* Keyframes */
7
7
  @keyframes seam-slide-in-left {
8
- from { transform: translateX(100%); }
9
- to { transform: translateX(0); }
8
+ from {
9
+ transform: translateX(100%);
10
+ }
11
+ to {
12
+ transform: translateX(0);
13
+ }
10
14
  }
11
15
 
12
16
  @keyframes seam-slide-in-right {
13
- from { transform: translateX(-100%); }
14
- to { transform: translateX(0); }
17
+ from {
18
+ transform: translateX(-100%);
19
+ }
20
+ to {
21
+ transform: translateX(0);
22
+ }
15
23
  }
16
24
 
17
25
  @keyframes seam-slide-out-left {
18
- from { transform: translateX(0); }
19
- to { transform: translateX(-100%); }
26
+ from {
27
+ transform: translateX(0);
28
+ }
29
+ to {
30
+ transform: translateX(-100%);
31
+ }
20
32
  }
21
33
 
22
34
  @keyframes seam-slide-out-right {
23
- from { transform: translateX(0); }
24
- to { transform: translateX(100%); }
35
+ from {
36
+ transform: translateX(0);
37
+ }
38
+ to {
39
+ transform: translateX(100%);
40
+ }
25
41
  }
26
42
 
27
43
  /*
@@ -94,57 +110,91 @@ html[data-route-direction]::view-transition-new(root) {
94
110
  */
95
111
 
96
112
  /* Sibling swap: current slides right, new slides left */
97
- html[data-route-direction="sibling"]::view-transition-old(seam-route-content-0),
98
- html[data-route-direction="sibling"]::view-transition-old(seam-route-content-1),
99
- html[data-route-direction="sibling"]::view-transition-old(seam-route-content-2),
100
- html[data-route-direction="sibling"]::view-transition-old(seam-route-content-3),
101
- html[data-route-direction="sibling"]::view-transition-old(seam-route-content-4),
102
- html[data-route-direction="sibling"]::view-transition-old(seam-route-content-5) {
103
- animation: var(--seam-route-transition-duration) var(--seam-route-transition-easing) both seam-slide-out-right;
104
- }
105
- html[data-route-direction="sibling"]::view-transition-new(seam-route-content-0),
106
- html[data-route-direction="sibling"]::view-transition-new(seam-route-content-1),
107
- html[data-route-direction="sibling"]::view-transition-new(seam-route-content-2),
108
- html[data-route-direction="sibling"]::view-transition-new(seam-route-content-3),
109
- html[data-route-direction="sibling"]::view-transition-new(seam-route-content-4),
110
- html[data-route-direction="sibling"]::view-transition-new(seam-route-content-5) {
111
- animation: var(--seam-route-transition-duration) var(--seam-route-transition-easing) both seam-slide-in-left;
113
+ html[data-route-direction='sibling']::view-transition-old(seam-route-content-0),
114
+ html[data-route-direction='sibling']::view-transition-old(seam-route-content-1),
115
+ html[data-route-direction='sibling']::view-transition-old(seam-route-content-2),
116
+ html[data-route-direction='sibling']::view-transition-old(seam-route-content-3),
117
+ html[data-route-direction='sibling']::view-transition-old(seam-route-content-4),
118
+ html[data-route-direction='sibling']::view-transition-old(
119
+ seam-route-content-5
120
+ ) {
121
+ animation: var(--seam-route-transition-duration)
122
+ var(--seam-route-transition-easing) both seam-slide-out-right;
123
+ }
124
+ html[data-route-direction='sibling']::view-transition-new(seam-route-content-0),
125
+ html[data-route-direction='sibling']::view-transition-new(seam-route-content-1),
126
+ html[data-route-direction='sibling']::view-transition-new(seam-route-content-2),
127
+ html[data-route-direction='sibling']::view-transition-new(seam-route-content-3),
128
+ html[data-route-direction='sibling']::view-transition-new(seam-route-content-4),
129
+ html[data-route-direction='sibling']::view-transition-new(
130
+ seam-route-content-5
131
+ ) {
132
+ animation: var(--seam-route-transition-duration)
133
+ var(--seam-route-transition-easing) both seam-slide-in-left;
112
134
  }
113
135
 
114
136
  /* Deeper: both slide left */
115
- html[data-route-direction="deeper"]::view-transition-old(seam-route-content-0),
116
- html[data-route-direction="deeper"]::view-transition-old(seam-route-content-1),
117
- html[data-route-direction="deeper"]::view-transition-old(seam-route-content-2),
118
- html[data-route-direction="deeper"]::view-transition-old(seam-route-content-3),
119
- html[data-route-direction="deeper"]::view-transition-old(seam-route-content-4),
120
- html[data-route-direction="deeper"]::view-transition-old(seam-route-content-5) {
121
- animation: var(--seam-route-transition-duration) var(--seam-route-transition-easing) both seam-slide-out-left;
122
- }
123
- html[data-route-direction="deeper"]::view-transition-new(seam-route-content-0),
124
- html[data-route-direction="deeper"]::view-transition-new(seam-route-content-1),
125
- html[data-route-direction="deeper"]::view-transition-new(seam-route-content-2),
126
- html[data-route-direction="deeper"]::view-transition-new(seam-route-content-3),
127
- html[data-route-direction="deeper"]::view-transition-new(seam-route-content-4),
128
- html[data-route-direction="deeper"]::view-transition-new(seam-route-content-5) {
129
- animation: var(--seam-route-transition-duration) var(--seam-route-transition-easing) both seam-slide-in-left;
137
+ html[data-route-direction='deeper']::view-transition-old(seam-route-content-0),
138
+ html[data-route-direction='deeper']::view-transition-old(seam-route-content-1),
139
+ html[data-route-direction='deeper']::view-transition-old(seam-route-content-2),
140
+ html[data-route-direction='deeper']::view-transition-old(seam-route-content-3),
141
+ html[data-route-direction='deeper']::view-transition-old(seam-route-content-4),
142
+ html[data-route-direction='deeper']::view-transition-old(seam-route-content-5) {
143
+ animation: var(--seam-route-transition-duration)
144
+ var(--seam-route-transition-easing) both seam-slide-out-left;
145
+ }
146
+ html[data-route-direction='deeper']::view-transition-new(seam-route-content-0),
147
+ html[data-route-direction='deeper']::view-transition-new(seam-route-content-1),
148
+ html[data-route-direction='deeper']::view-transition-new(seam-route-content-2),
149
+ html[data-route-direction='deeper']::view-transition-new(seam-route-content-3),
150
+ html[data-route-direction='deeper']::view-transition-new(seam-route-content-4),
151
+ html[data-route-direction='deeper']::view-transition-new(seam-route-content-5) {
152
+ animation: var(--seam-route-transition-duration)
153
+ var(--seam-route-transition-easing) both seam-slide-in-left;
130
154
  }
131
155
 
132
156
  /* Shallower: both slide right */
133
- html[data-route-direction="shallower"]::view-transition-old(seam-route-content-0),
134
- html[data-route-direction="shallower"]::view-transition-old(seam-route-content-1),
135
- html[data-route-direction="shallower"]::view-transition-old(seam-route-content-2),
136
- html[data-route-direction="shallower"]::view-transition-old(seam-route-content-3),
137
- html[data-route-direction="shallower"]::view-transition-old(seam-route-content-4),
138
- html[data-route-direction="shallower"]::view-transition-old(seam-route-content-5) {
139
- animation: var(--seam-route-transition-duration) var(--seam-route-transition-easing) both seam-slide-out-right;
140
- }
141
- html[data-route-direction="shallower"]::view-transition-new(seam-route-content-0),
142
- html[data-route-direction="shallower"]::view-transition-new(seam-route-content-1),
143
- html[data-route-direction="shallower"]::view-transition-new(seam-route-content-2),
144
- html[data-route-direction="shallower"]::view-transition-new(seam-route-content-3),
145
- html[data-route-direction="shallower"]::view-transition-new(seam-route-content-4),
146
- html[data-route-direction="shallower"]::view-transition-new(seam-route-content-5) {
147
- animation: var(--seam-route-transition-duration) var(--seam-route-transition-easing) both seam-slide-in-right;
157
+ html[data-route-direction='shallower']::view-transition-old(
158
+ seam-route-content-0
159
+ ),
160
+ html[data-route-direction='shallower']::view-transition-old(
161
+ seam-route-content-1
162
+ ),
163
+ html[data-route-direction='shallower']::view-transition-old(
164
+ seam-route-content-2
165
+ ),
166
+ html[data-route-direction='shallower']::view-transition-old(
167
+ seam-route-content-3
168
+ ),
169
+ html[data-route-direction='shallower']::view-transition-old(
170
+ seam-route-content-4
171
+ ),
172
+ html[data-route-direction='shallower']::view-transition-old(
173
+ seam-route-content-5
174
+ ) {
175
+ animation: var(--seam-route-transition-duration)
176
+ var(--seam-route-transition-easing) both seam-slide-out-right;
177
+ }
178
+ html[data-route-direction='shallower']::view-transition-new(
179
+ seam-route-content-0
180
+ ),
181
+ html[data-route-direction='shallower']::view-transition-new(
182
+ seam-route-content-1
183
+ ),
184
+ html[data-route-direction='shallower']::view-transition-new(
185
+ seam-route-content-2
186
+ ),
187
+ html[data-route-direction='shallower']::view-transition-new(
188
+ seam-route-content-3
189
+ ),
190
+ html[data-route-direction='shallower']::view-transition-new(
191
+ seam-route-content-4
192
+ ),
193
+ html[data-route-direction='shallower']::view-transition-new(
194
+ seam-route-content-5
195
+ ) {
196
+ animation: var(--seam-route-transition-duration)
197
+ var(--seam-route-transition-easing) both seam-slide-in-right;
148
198
  }
149
199
 
150
200
  /* Reduced motion: disable all route transition animations */
@@ -8,7 +8,7 @@ import * as apollo_angular from 'apollo-angular';
8
8
  import { QueryRef, WatchQueryOptions, Apollo } from 'apollo-angular';
9
9
  import { DataFilterState } from '@theseam/ui-common/data-filters';
10
10
  import * as i0 from '@angular/core';
11
- import { InjectionToken, Type, Provider, EventEmitter } from '@angular/core';
11
+ import { InjectionToken, Type, Provider, OutputRef, EventEmitter } from '@angular/core';
12
12
  import { OperationVariables } from '@apollo/client/core/types';
13
13
  import * as _fortawesome_fontawesome_common_types from '@fortawesome/fontawesome-common-types';
14
14
  import { IDataExporter } from '@theseam/ui-common/data-exporter';
@@ -192,7 +192,7 @@ declare class GQLVariable {
192
192
  constructor(name: string, type: string);
193
193
  }
194
194
 
195
- type GqlDatatableAccessor = Pick<DatatableComponent, 'page' | 'sort' | 'sorts' | 'filterStates' | 'pageInfo' | 'externalSorting' | 'columns$'> & {
195
+ type GqlDatatableAccessor = Pick<DatatableComponent, 'page' | 'sort' | 'sorts' | 'filterStates' | 'pageInfo' | 'externalSorting' | 'columns$' | 'refreshRequested'> & {
196
196
  ngxDatatable: {
197
197
  offset: number;
198
198
  pageSize: number;
@@ -711,6 +711,10 @@ declare class MockDatatable implements GqlDatatableAccessor {
711
711
  private readonly _columnsSubject;
712
712
  readonly columns$: Observable<TheSeamDatatableColumn[]>;
713
713
  private readonly _filterStatesSubject;
714
+ private readonly _refreshSubject;
715
+ readonly refreshRequested: OutputRef<void>;
716
+ /** Test helper: simulate the refresh button being clicked. */
717
+ triggerRefresh(): void;
714
718
  private _sorts;
715
719
  private _rows;
716
720
  private _offset;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theseam/ui-common",
3
- "version": "1.0.2-beta.60",
3
+ "version": "1.0.2-beta.67",
4
4
  "peerDependencies": {
5
5
  "@angular/cdk": "^20.2.3",
6
6
  "@angular/common": "^20.3.0",
@@ -191,6 +191,10 @@
191
191
  "types": "./dynamic-component-loader/index.d.ts",
192
192
  "default": "./fesm2022/theseam-ui-common-dynamic-component-loader.mjs"
193
193
  },
194
+ "./file-input": {
195
+ "types": "./file-input/index.d.ts",
196
+ "default": "./fesm2022/theseam-ui-common-file-input.mjs"
197
+ },
194
198
  "./footer-bar": {
195
199
  "types": "./footer-bar/index.d.ts",
196
200
  "default": "./fesm2022/theseam-ui-common-footer-bar.mjs"
@@ -4,7 +4,6 @@ import * as _angular_core from '@angular/core';
4
4
  import { InjectionToken, AfterViewInit, EventEmitter } from '@angular/core';
5
5
  import * as _fortawesome_fontawesome_common_types from '@fortawesome/fontawesome-common-types';
6
6
  import { FormGroup, FormControl, ControlValueAccessor } from '@angular/forms';
7
- import { NgxFileDropEntry } from 'ngx-file-drop';
8
7
  import { ModalConfig } from '@theseam/ui-common/modal';
9
8
  import * as _angular_cdk_testing from '@angular/cdk/testing';
10
9
  import { ComponentHarness, TestElement, BaseHarnessFilters, HarnessPredicate } from '@angular/cdk/testing';
@@ -153,24 +152,13 @@ declare class TheSeamSignatureInputImgComponent implements ControlValueAccessor,
153
152
  static readonly MAX_FILE_SIZE: number;
154
153
  private readonly _container;
155
154
  private readonly _destroyRef;
156
- /**
157
- * The File is only needed for validation at selection time. Once it's been
158
- * converted to a data URL and stored in the form value, we don't need the
159
- * File again — so there's no point trying to round-trip it through
160
- * writeValue / form state. The preview renders off the current form value.
161
- */
162
155
  protected readonly _fileControl: FormControl<File | null>;
163
156
  private readonly _fileStatus;
164
157
  protected readonly _sizeError: _angular_core.Signal<string | null>;
165
- /**
166
- * Single source of truth for both the form value and the preview image.
167
- * External writes (writeValue) and successful uploads both funnel through
168
- * here, so switching tabs and coming back always shows the last committed
169
- * signature.
170
- */
171
158
  private readonly _value;
172
159
  protected readonly _previewDataUrl: _angular_core.Signal<string | null>;
173
160
  protected readonly _previewBackgroundImage: _angular_core.Signal<string | null>;
161
+ private readonly _nativeInput;
174
162
  private _onChange;
175
163
  private _onTouched;
176
164
  constructor();
@@ -180,7 +168,8 @@ declare class TheSeamSignatureInputImgComponent implements ControlValueAccessor,
180
168
  setDisabledState(isDisabled: boolean): void;
181
169
  clear(): void;
182
170
  openFileBrowse(): void;
183
- protected _onFileDropped(files: NgxFileDropEntry[]): void;
171
+ protected _onFilesDropped(files: File[]): void;
172
+ protected _onNativeChange(event: Event): void;
184
173
  private _setValue;
185
174
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TheSeamSignatureInputImgComponent, never>;
186
175
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<TheSeamSignatureInputImgComponent, "seam-signature-input-img", never, {}, {}, never, never, true, never>;