@scaleflex/uploader 0.1.0

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/LICENSE +50 -0
  3. package/README.md +123 -0
  4. package/dist/auth/auth.service.d.ts +25 -0
  5. package/dist/auth/auth.service.d.ts.map +1 -0
  6. package/dist/auth/auth.types.d.ts +24 -0
  7. package/dist/auth/auth.types.d.ts.map +1 -0
  8. package/dist/auth/index.d.ts +3 -0
  9. package/dist/auth/index.d.ts.map +1 -0
  10. package/dist/components/actions-bar.d.ts +17 -0
  11. package/dist/components/actions-bar.d.ts.map +1 -0
  12. package/dist/components/camera-dialog.d.ts +27 -0
  13. package/dist/components/camera-dialog.d.ts.map +1 -0
  14. package/dist/components/drop-zone.d.ts +28 -0
  15. package/dist/components/drop-zone.d.ts.map +1 -0
  16. package/dist/components/file-item.d.ts +12 -0
  17. package/dist/components/file-item.d.ts.map +1 -0
  18. package/dist/components/file-list.d.ts +8 -0
  19. package/dist/components/file-list.d.ts.map +1 -0
  20. package/dist/components/import-divider.d.ts +6 -0
  21. package/dist/components/import-divider.d.ts.map +1 -0
  22. package/dist/components/index.d.ts +9 -0
  23. package/dist/components/index.d.ts.map +1 -0
  24. package/dist/components/provider-browser.d.ts +48 -0
  25. package/dist/components/provider-browser.d.ts.map +1 -0
  26. package/dist/components/screen-cast-dialog.d.ts +29 -0
  27. package/dist/components/screen-cast-dialog.d.ts.map +1 -0
  28. package/dist/components/search-provider-browser.d.ts +36 -0
  29. package/dist/components/search-provider-browser.d.ts.map +1 -0
  30. package/dist/components/source-pills.d.ts +11 -0
  31. package/dist/components/source-pills.d.ts.map +1 -0
  32. package/dist/components/success-card.d.ts +10 -0
  33. package/dist/components/success-card.d.ts.map +1 -0
  34. package/dist/components/url-dialog.d.ts +25 -0
  35. package/dist/components/url-dialog.d.ts.map +1 -0
  36. package/dist/connectors/companion-client.d.ts +58 -0
  37. package/dist/connectors/companion-client.d.ts.map +1 -0
  38. package/dist/connectors/connector.types.d.ts +56 -0
  39. package/dist/connectors/connector.types.d.ts.map +1 -0
  40. package/dist/connectors/index.d.ts +5 -0
  41. package/dist/connectors/index.d.ts.map +1 -0
  42. package/dist/connectors/provider-registry.d.ts +8 -0
  43. package/dist/connectors/provider-registry.d.ts.map +1 -0
  44. package/dist/connectors/token-store.d.ts +10 -0
  45. package/dist/connectors/token-store.d.ts.map +1 -0
  46. package/dist/controllers/store.controller.d.ts +14 -0
  47. package/dist/controllers/store.controller.d.ts.map +1 -0
  48. package/dist/define.cjs +1 -0
  49. package/dist/define.d.ts +2 -0
  50. package/dist/define.d.ts.map +1 -0
  51. package/dist/define.js +15 -0
  52. package/dist/engine/companion-upload.d.ts +23 -0
  53. package/dist/engine/companion-upload.d.ts.map +1 -0
  54. package/dist/engine/index.d.ts +2 -0
  55. package/dist/engine/index.d.ts.map +1 -0
  56. package/dist/engine/upload-engine.d.ts +56 -0
  57. package/dist/engine/upload-engine.d.ts.map +1 -0
  58. package/dist/engine/xhr-upload.d.ts +25 -0
  59. package/dist/engine/xhr-upload.d.ts.map +1 -0
  60. package/dist/events/event-bus.d.ts +38 -0
  61. package/dist/events/event-bus.d.ts.map +1 -0
  62. package/dist/events/public-events.d.ts +23 -0
  63. package/dist/events/public-events.d.ts.map +1 -0
  64. package/dist/index.cjs +1 -0
  65. package/dist/index.d.ts +17 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +21 -0
  68. package/dist/provider-browser-C-S_MPrC.js +832 -0
  69. package/dist/provider-browser-CmCwv0ph.cjs +581 -0
  70. package/dist/react.cjs +1 -0
  71. package/dist/react.d.ts +33 -0
  72. package/dist/react.d.ts.map +1 -0
  73. package/dist/react.js +125 -0
  74. package/dist/search-provider-browser-DxmLznEB.cjs +390 -0
  75. package/dist/search-provider-browser-jCOer2Y9.js +537 -0
  76. package/dist/sfx-uploader-BVDK-9xi.cjs +2029 -0
  77. package/dist/sfx-uploader-C2lWIRnU.js +3789 -0
  78. package/dist/sfx-uploader.d.ts +131 -0
  79. package/dist/sfx-uploader.d.ts.map +1 -0
  80. package/dist/store/helpers.d.ts +16 -0
  81. package/dist/store/helpers.d.ts.map +1 -0
  82. package/dist/store/index.d.ts +7 -0
  83. package/dist/store/index.d.ts.map +1 -0
  84. package/dist/store/store.d.ts +14 -0
  85. package/dist/store/store.d.ts.map +1 -0
  86. package/dist/store/store.types.d.ts +77 -0
  87. package/dist/store/store.types.d.ts.map +1 -0
  88. package/dist/test-utils.d.ts +5 -0
  89. package/dist/test-utils.d.ts.map +1 -0
  90. package/dist/types/source.types.d.ts +12 -0
  91. package/dist/types/source.types.d.ts.map +1 -0
  92. package/dist/utils/file-utils.d.ts +14 -0
  93. package/dist/utils/file-utils.d.ts.map +1 -0
  94. package/dist/utils/validate.d.ts +6 -0
  95. package/dist/utils/validate.d.ts.map +1 -0
  96. package/package.json +72 -0
@@ -0,0 +1,581 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("lit"),l=require("lit/decorators.js"),c=require("./sfx-uploader-BVDK-9xi.cjs"),x="sfx-uploader-token:";function p(o){try{return localStorage.getItem(`${x}${o}`)}catch{return null}}function g(o,e){try{localStorage.setItem(`${x}${o}`,e)}catch{}}function f(o){try{localStorage.removeItem(`${x}${o}`)}catch{}}function v(o,e){const i=r=>{if(r.origin!==new URL(o).origin)return;const t=typeof r.data=="string"?_(r.data):r.data;t!=null&&t.token&&e(t.token)};return window.addEventListener("message",i),()=>window.removeEventListener("message",i)}function _(o){try{return JSON.parse(o)}catch{return null}}var k=Object.defineProperty,d=(o,e,i,r)=>{for(var t=void 0,n=o.length-1,h;n>=0;n--)(h=o[n])&&(t=h(e,i,t)||t);return t&&k(e,i,t),t};const m=class m extends s.LitElement{constructor(){super(...arguments),this.provider="google-drive",this.companionUrl="",this._authenticated=!1,this._loading=!1,this._items=[],this._selectedIds=new Set,this._breadcrumbs=[],this._nextPagePath=null,this._error=null,this._loadingMore=!1,this._username=null,this._cleanupAuthListener=null,this._authWindow=null,this._handleConnect=()=>{var i;const e=c.getAuthUrl(this.companionUrl,this.provider);this._authWindow=window.open(e,"_blank","width=600,height=600"),(i=this._cleanupAuthListener)==null||i.call(this),this._cleanupAuthListener=v(this.companionUrl,r=>{var t,n;(t=this._authWindow)==null||t.close(),this._authWindow=null,(n=this._cleanupAuthListener)==null||n.call(this),this._cleanupAuthListener=null,g(this.provider,r),this._authenticated=!0,this._loadFolder("")})},this._lastClickedIndex=null,this._toggleSelectAll=()=>{const e=this._items.filter(r=>!r.isFolder);e.every(r=>this._selectedIds.has(r.id))?this._selectedIds=new Set:this._selectedIds=new Set(e.map(r=>r.id))},this._onAddSelected=()=>{const e=p(this.provider);if(!e)return;const r=this._items.filter(t=>!t.isFolder&&this._selectedIds.has(t.id)).map(t=>({companionUrl:this.companionUrl,provider:this.provider,token:e,requestPath:t.requestPath,fileId:t.id,name:t.name,mimeType:t.mimeType,size:t.size,thumbnail:t.thumbnail}));this.dispatchEvent(new CustomEvent("connector-files-selected",{detail:{files:r},bubbles:!0,composed:!0}))},this._onClose=()=>{this.dispatchEvent(new CustomEvent("connector-close",{bubbles:!0,composed:!0}))},this._handleLogout=async()=>{const e=p(this.provider);if(e){try{await c.logout(this.companionUrl,this.provider,e)}catch{}f(this.provider)}this._reset()}}connectedCallback(){super.connectedCallback(),this._checkAuth()}disconnectedCallback(){var e;super.disconnectedCallback(),(e=this._cleanupAuthListener)==null||e.call(this),this._cleanupAuthListener=null}updated(e){e.has("provider")&&(this._reset(),this._checkAuth())}_reset(){this._authenticated=!1,this._loading=!1,this._items=[],this._selectedIds=new Set,this._breadcrumbs=[],this._nextPagePath=null,this._error=null,this._username=null}_checkAuth(){p(this.provider)&&(this._authenticated=!0,this._loadFolder(""))}get _providerLabel(){var i;return((i=c.getProviderSources([this.provider])[0])==null?void 0:i.label)??this.provider}async _loadFolder(e){const i=p(this.provider);if(!i){this._authenticated=!1;return}this.offsetHeight>0&&(this.style.minHeight=`${this.offsetHeight}px`),this._loading=!0,this._error=null,this._items=[],this._selectedIds=new Set,this._lastClickedIndex=null,this._nextPagePath=null;try{const r=await c.listFiles(this.companionUrl,this.provider,i,e);this._items=r.items,this._nextPagePath=r.nextPagePath,r.username&&(this._username=r.username)}catch(r){r instanceof c.AuthExpiredError?(f(this.provider),this._authenticated=!1):this._error=r instanceof Error?r.message:"Failed to load files"}finally{this._loading=!1}}_onFolderClick(e){this._breadcrumbs=[...this._breadcrumbs,{name:e.name,path:e.requestPath}],this._loadFolder(e.requestPath)}_onBreadcrumbClick(e){if(e<0)this._breadcrumbs=[],this._loadFolder("");else{const i=this._breadcrumbs[e];this._breadcrumbs=this._breadcrumbs.slice(0,e+1),this._loadFolder(i.path)}}async _onLoadMore(){const e=p(this.provider);if(!(!e||!this._nextPagePath)){this._loadingMore=!0;try{const i=await c.listNextPage(this.companionUrl,e,this._nextPagePath);this._items=[...this._items,...i.items],this._nextPagePath=i.nextPagePath}catch(i){i instanceof c.AuthExpiredError&&(f(this.provider),this._authenticated=!1)}finally{this._loadingMore=!1}}}_toggleSelect(e,i){const r=this._items.filter(n=>!n.isFolder),t=r.findIndex(n=>n.id===e.id);if(i!=null&&i.shiftKey&&this._lastClickedIndex!==null&&t!==-1){const n=Math.min(this._lastClickedIndex,t),h=Math.max(this._lastClickedIndex,t),b=new Set(this._selectedIds);for(let u=n;u<=h;u++)b.add(r[u].id);this._selectedIds=b}else{const n=new Set(this._selectedIds);n.has(e.id)?n.delete(e.id):n.add(e.id),this._selectedIds=n}t!==-1&&(this._lastClickedIndex=t)}render(){return s.html`
2
+ ${this._renderHeader()}
3
+ ${this._authenticated?this._loading?this._renderLoading():this._error?this._renderError():this._renderBrowser():this._renderAuthView()}
4
+ `}_renderHeader(){return s.html`
5
+ <div class="browser-header">
6
+ <button class="back-btn" @click=${this._onClose}>
7
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
8
+ <polyline points="15 18 9 12 15 6" />
9
+ </svg>
10
+ </button>
11
+ <span class="browser-title">${this._providerLabel}</span>
12
+ ${this._authenticated?s.html`
13
+ ${this._username?s.html`<span class="username">${this._username}</span>`:s.nothing}
14
+ <button class="logout-btn" @click=${this._handleLogout}>Log out</button>
15
+ `:s.nothing}
16
+ </div>
17
+ `}_renderAuthView(){return s.html`
18
+ <div class="auth-view">
19
+ <div class="auth-icon">
20
+ <svg viewBox="0 0 24 24"><path d="M12 2a5 5 0 015 5v3h1a2 2 0 012 2v8a2 2 0 01-2 2H6a2 2 0 01-2-2v-8a2 2 0 012-2h1V7a5 5 0 015-5zm3 8H9v-3a3 3 0 016 0v3z" fill="currentColor"/></svg>
21
+ </div>
22
+ <div class="auth-text">
23
+ Connect to ${this._providerLabel} to browse and select files
24
+ </div>
25
+ <button class="connect-btn" @click=${this._handleConnect}>
26
+ Connect to ${this._providerLabel}
27
+ </button>
28
+ </div>
29
+ `}_renderLoading(){const e=[1,2,3,4,5,6];return s.html`
30
+ <div class="skeleton-list">
31
+ ${e.map(()=>s.html`
32
+ <div class="skeleton-row">
33
+ <div class="skeleton-check"></div>
34
+ <div class="skeleton-thumb"></div>
35
+ <div class="skeleton-text">
36
+ <div class="skeleton-name"></div>
37
+ <div class="skeleton-size"></div>
38
+ </div>
39
+ </div>
40
+ `)}
41
+ </div>
42
+ `}_renderError(){return s.html`
43
+ <div class="error-view">
44
+ <div class="error-text">${this._error}</div>
45
+ <button class="retry-btn" @click=${()=>{const e=this._breadcrumbs[this._breadcrumbs.length-1];this._loadFolder((e==null?void 0:e.path)??"")}}>
46
+ Retry
47
+ </button>
48
+ </div>
49
+ `}_renderBrowser(){const e=this._items.filter(t=>!t.isFolder),i=this._items.filter(t=>t.isFolder),r=this._selectedIds.size;return s.html`
50
+ ${this._renderBreadcrumbs()}
51
+
52
+ <div class="file-list">
53
+ ${i.length===0&&e.length===0?s.html`<div class="empty-state"><div class="empty-text">This folder is empty</div></div>`:s.nothing}
54
+
55
+ ${i.map(t=>s.html`
56
+ <div class="file-item" @click=${()=>this._onFolderClick(t)}>
57
+ <div class="file-thumb">
58
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
59
+ <path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" />
60
+ </svg>
61
+ </div>
62
+ <div class="file-info">
63
+ <div class="file-name">${t.name}</div>
64
+ </div>
65
+ </div>
66
+ `)}
67
+
68
+ ${e.map(t=>s.html`
69
+ <div
70
+ class="file-item ${this._selectedIds.has(t.id)?"selected":""}"
71
+ @click=${n=>this._toggleSelect(t,n)}
72
+ >
73
+ <input
74
+ type="checkbox"
75
+ .checked=${this._selectedIds.has(t.id)}
76
+ @click=${n=>n.stopPropagation()}
77
+ @change=${()=>this._toggleSelect(t)}
78
+ />
79
+ <div class="file-thumb">
80
+ ${t.thumbnail?s.html`<img src=${t.thumbnail} alt="" loading="lazy" referrerpolicy="no-referrer"
81
+ @error=${n=>{const h=n.target;h.style.display="none",h.parentElement.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>'}}
82
+ />`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
83
+ <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
84
+ <polyline points="14 2 14 8 20 8" />
85
+ </svg>`}
86
+ </div>
87
+ <div class="file-info">
88
+ <div class="file-name">${t.name}</div>
89
+ ${t.size?s.html`<div class="file-size">${y(t.size)}</div>`:s.nothing}
90
+ </div>
91
+ </div>
92
+ `)}
93
+
94
+ ${this._nextPagePath?s.html`
95
+ <button
96
+ class="load-more-btn"
97
+ ?disabled=${this._loadingMore}
98
+ @click=${this._onLoadMore}
99
+ >
100
+ ${this._loadingMore?"Loading...":"Load more"}
101
+ </button>
102
+ `:s.nothing}
103
+ </div>
104
+
105
+ ${e.length>0?s.html`
106
+ <div class="browser-footer">
107
+ <button class="select-all-btn" @click=${this._toggleSelectAll}>
108
+ ${e.every(t=>this._selectedIds.has(t.id))?"Deselect all":"Select all"}
109
+ </button>
110
+ <span class="selected-count">
111
+ ${r>0?`${r} file${r===1?"":"s"} selected`:"Select files to add"}
112
+ </span>
113
+ <button
114
+ class="add-btn"
115
+ ?disabled=${r===0}
116
+ @click=${this._onAddSelected}
117
+ >
118
+ Add ${r>0?r:""} file${r===1?"":"s"}
119
+ </button>
120
+ </div>
121
+ `:s.nothing}
122
+ `}_renderBreadcrumbs(){return this._breadcrumbs.length===0?s.nothing:s.html`
123
+ <div class="breadcrumbs">
124
+ <button class="crumb" @click=${()=>this._onBreadcrumbClick(-1)}>Root</button>
125
+ ${this._breadcrumbs.map((e,i)=>s.html`
126
+ <span class="crumb-sep">/</span>
127
+ ${i<this._breadcrumbs.length-1?s.html`<button class="crumb" @click=${()=>this._onBreadcrumbClick(i)}>${e.name}</button>`:s.html`<span class="crumb-current">${e.name}</span>`}
128
+ `)}
129
+ </div>
130
+ `}};m.styles=s.css`
131
+ :host {
132
+ display: flex;
133
+ flex-direction: column;
134
+ height: 100%;
135
+ min-height: 300px;
136
+ font-family: var(--sfx-up-font, 'Inter', system-ui, -apple-system, sans-serif);
137
+ color: var(--sfx-up-text, #1e293b);
138
+ }
139
+
140
+ /* --- Header --- */
141
+ .browser-header {
142
+ display: flex;
143
+ align-items: center;
144
+ gap: 10px;
145
+ padding: 14px 20px;
146
+ border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
147
+ flex-shrink: 0;
148
+ }
149
+
150
+ .back-btn {
151
+ width: 32px;
152
+ height: 32px;
153
+ border: none;
154
+ background: none;
155
+ border-radius: 8px;
156
+ cursor: pointer;
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ color: var(--sfx-up-text-muted, #94a3b8);
161
+ transition: all 0.15s;
162
+ flex-shrink: 0;
163
+ }
164
+
165
+ .back-btn:hover {
166
+ background: #f1f5f9;
167
+ color: var(--sfx-up-text, #1e293b);
168
+ }
169
+
170
+ .back-btn svg {
171
+ width: 18px;
172
+ height: 18px;
173
+ }
174
+
175
+ .browser-title {
176
+ font-size: 14px;
177
+ font-weight: 600;
178
+ flex: 1;
179
+ }
180
+
181
+ .logout-btn {
182
+ border: none;
183
+ background: none;
184
+ font-family: inherit;
185
+ font-size: 12px;
186
+ color: var(--sfx-up-text-muted, #94a3b8);
187
+ cursor: pointer;
188
+ padding: 4px 8px;
189
+ border-radius: 6px;
190
+ transition: all 0.15s;
191
+ flex-shrink: 0;
192
+ }
193
+
194
+ .logout-btn:hover {
195
+ background: #fef2f2;
196
+ color: var(--sfx-up-error, #dc2626);
197
+ }
198
+
199
+ .username {
200
+ font-size: 12px;
201
+ color: var(--sfx-up-text-muted, #94a3b8);
202
+ flex-shrink: 0;
203
+ }
204
+
205
+ /* --- Auth view --- */
206
+ .auth-view {
207
+ flex: 1;
208
+ display: flex;
209
+ flex-direction: column;
210
+ align-items: center;
211
+ justify-content: center;
212
+ gap: 16px;
213
+ padding: 40px 24px;
214
+ text-align: center;
215
+ }
216
+
217
+ .auth-icon {
218
+ width: 56px;
219
+ height: 56px;
220
+ border-radius: 16px;
221
+ background: var(--sfx-up-primary-bg, #eff6ff);
222
+ color: var(--sfx-up-primary, #2563eb);
223
+ display: flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ }
227
+
228
+ .auth-icon svg {
229
+ width: 28px;
230
+ height: 28px;
231
+ fill: currentColor;
232
+ }
233
+
234
+ .auth-text {
235
+ font-size: 14px;
236
+ color: var(--sfx-up-text-secondary, #475569);
237
+ max-width: 280px;
238
+ }
239
+
240
+ .connect-btn {
241
+ height: 40px;
242
+ padding: 0 24px;
243
+ border: none;
244
+ border-radius: 10px;
245
+ background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
246
+ color: #fff;
247
+ font-family: inherit;
248
+ font-size: 14px;
249
+ font-weight: 600;
250
+ cursor: pointer;
251
+ transition: all 0.18s;
252
+ box-shadow: 0 2px 10px rgba(37, 99, 235, 0.28);
253
+ }
254
+
255
+ .connect-btn:hover {
256
+ transform: translateY(-1px);
257
+ box-shadow: 0 4px 16px rgba(37, 99, 235, 0.38);
258
+ }
259
+
260
+ /* --- Breadcrumbs --- */
261
+ .breadcrumbs {
262
+ display: flex;
263
+ align-items: center;
264
+ gap: 4px;
265
+ padding: 10px 20px;
266
+ font-size: 12px;
267
+ color: var(--sfx-up-text-muted, #94a3b8);
268
+ border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
269
+ flex-shrink: 0;
270
+ flex-wrap: wrap;
271
+ }
272
+
273
+ .crumb {
274
+ cursor: pointer;
275
+ color: var(--sfx-up-primary, #2563eb);
276
+ border: none;
277
+ background: none;
278
+ font-family: inherit;
279
+ font-size: 12px;
280
+ padding: 2px 4px;
281
+ border-radius: 4px;
282
+ transition: background 0.15s;
283
+ }
284
+
285
+ .crumb:hover {
286
+ background: var(--sfx-up-primary-bg, #eff6ff);
287
+ }
288
+
289
+ .crumb-sep {
290
+ color: var(--sfx-up-text-muted, #94a3b8);
291
+ }
292
+
293
+ .crumb-current {
294
+ color: var(--sfx-up-text, #1e293b);
295
+ font-weight: 500;
296
+ }
297
+
298
+ /* --- File list --- */
299
+ .file-list {
300
+ flex: 1;
301
+ overflow-y: auto;
302
+ padding: 8px 12px;
303
+ min-height: 0;
304
+ }
305
+
306
+ .file-item {
307
+ display: flex;
308
+ align-items: center;
309
+ gap: 12px;
310
+ padding: 10px 12px;
311
+ border-radius: 10px;
312
+ cursor: pointer;
313
+ transition: background 0.15s;
314
+ user-select: none;
315
+ }
316
+
317
+ .file-item:hover {
318
+ background: #f8fafc;
319
+ }
320
+
321
+ .file-item.selected {
322
+ background: var(--sfx-up-primary-bg, #eff6ff);
323
+ }
324
+
325
+ .file-item input[type='checkbox'] {
326
+ width: 16px;
327
+ height: 16px;
328
+ accent-color: var(--sfx-up-primary, #2563eb);
329
+ flex-shrink: 0;
330
+ cursor: pointer;
331
+ }
332
+
333
+ .file-thumb {
334
+ width: 36px;
335
+ height: 36px;
336
+ border-radius: 8px;
337
+ background: #f1f5f9;
338
+ display: flex;
339
+ align-items: center;
340
+ justify-content: center;
341
+ flex-shrink: 0;
342
+ overflow: hidden;
343
+ }
344
+
345
+ .file-thumb img {
346
+ width: 100%;
347
+ height: 100%;
348
+ object-fit: cover;
349
+ }
350
+
351
+ .file-thumb svg {
352
+ width: 18px;
353
+ height: 18px;
354
+ color: var(--sfx-up-text-muted, #94a3b8);
355
+ }
356
+
357
+ .file-info {
358
+ flex: 1;
359
+ min-width: 0;
360
+ }
361
+
362
+ .file-name {
363
+ font-size: 13px;
364
+ font-weight: 500;
365
+ white-space: nowrap;
366
+ overflow: hidden;
367
+ text-overflow: ellipsis;
368
+ }
369
+
370
+ .file-size {
371
+ font-size: 11px;
372
+ color: var(--sfx-up-text-muted, #94a3b8);
373
+ }
374
+
375
+ /* --- Footer --- */
376
+ .browser-footer {
377
+ display: flex;
378
+ align-items: center;
379
+ justify-content: space-between;
380
+ padding: 12px 20px;
381
+ border-top: 1px solid var(--sfx-up-border-light, #f1f5f9);
382
+ flex-shrink: 0;
383
+ }
384
+
385
+ .selected-count {
386
+ font-size: 13px;
387
+ color: var(--sfx-up-text-secondary, #475569);
388
+ font-weight: 500;
389
+ }
390
+
391
+ .add-btn {
392
+ height: 36px;
393
+ padding: 0 20px;
394
+ border: none;
395
+ border-radius: 9px;
396
+ background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
397
+ color: #fff;
398
+ font-family: inherit;
399
+ font-size: 13px;
400
+ font-weight: 600;
401
+ cursor: pointer;
402
+ transition: all 0.18s;
403
+ box-shadow: 0 2px 10px rgba(37, 99, 235, 0.28);
404
+ }
405
+
406
+ .add-btn:hover:not(:disabled) {
407
+ transform: translateY(-1px);
408
+ box-shadow: 0 4px 16px rgba(37, 99, 235, 0.38);
409
+ }
410
+
411
+ .add-btn:disabled {
412
+ opacity: 0.5;
413
+ cursor: not-allowed;
414
+ }
415
+
416
+ .select-all-btn {
417
+ border: none;
418
+ background: none;
419
+ font-family: inherit;
420
+ font-size: 12px;
421
+ font-weight: 600;
422
+ color: var(--sfx-up-primary, #2563eb);
423
+ cursor: pointer;
424
+ padding: 4px 8px;
425
+ border-radius: 6px;
426
+ transition: background 0.15s;
427
+ flex-shrink: 0;
428
+ }
429
+
430
+ .select-all-btn:hover {
431
+ background: var(--sfx-up-primary-bg, #eff6ff);
432
+ }
433
+
434
+ /* --- Loading / Error --- */
435
+ .loading, .error-view, .empty-state {
436
+ flex: 1;
437
+ display: flex;
438
+ flex-direction: column;
439
+ align-items: center;
440
+ justify-content: center;
441
+ gap: 12px;
442
+ padding: 40px 24px;
443
+ text-align: center;
444
+ }
445
+
446
+ .spinner {
447
+ width: 28px;
448
+ height: 28px;
449
+ border: 3px solid var(--sfx-up-border, #e8edf5);
450
+ border-top-color: var(--sfx-up-primary, #2563eb);
451
+ border-radius: 50%;
452
+ animation: spin 0.7s linear infinite;
453
+ }
454
+
455
+ .error-text {
456
+ font-size: 14px;
457
+ color: var(--sfx-up-error, #dc2626);
458
+ }
459
+
460
+ .retry-btn {
461
+ height: 34px;
462
+ padding: 0 16px;
463
+ border: 1.5px solid var(--sfx-up-border, #e8edf5);
464
+ background: none;
465
+ border-radius: 8px;
466
+ font-family: inherit;
467
+ font-size: 13px;
468
+ font-weight: 600;
469
+ cursor: pointer;
470
+ color: var(--sfx-up-text-secondary, #475569);
471
+ transition: all 0.15s;
472
+ }
473
+
474
+ .retry-btn:hover {
475
+ background: #f8faff;
476
+ border-color: #d1dff0;
477
+ }
478
+
479
+ .load-more-btn {
480
+ display: block;
481
+ margin: 8px auto;
482
+ padding: 8px 20px;
483
+ border: 1.5px solid var(--sfx-up-border, #e8edf5);
484
+ background: none;
485
+ border-radius: 8px;
486
+ font-family: inherit;
487
+ font-size: 13px;
488
+ font-weight: 500;
489
+ cursor: pointer;
490
+ color: var(--sfx-up-primary, #2563eb);
491
+ transition: all 0.15s;
492
+ }
493
+
494
+ .load-more-btn:hover {
495
+ background: var(--sfx-up-primary-bg, #eff6ff);
496
+ }
497
+
498
+ .empty-text {
499
+ font-size: 14px;
500
+ color: var(--sfx-up-text-muted, #94a3b8);
501
+ }
502
+
503
+ /* --- Skeleton loading --- */
504
+ .skeleton-list {
505
+ flex: 1;
506
+ padding: 8px 12px;
507
+ min-height: 0;
508
+ }
509
+
510
+ .skeleton-row {
511
+ display: flex;
512
+ align-items: center;
513
+ gap: 12px;
514
+ padding: 10px 12px;
515
+ }
516
+
517
+ .skeleton-check {
518
+ width: 16px;
519
+ height: 16px;
520
+ border-radius: 4px;
521
+ background: #f1f5f9;
522
+ }
523
+
524
+ .skeleton-thumb {
525
+ width: 36px;
526
+ height: 36px;
527
+ border-radius: 8px;
528
+ background: #f1f5f9;
529
+ flex-shrink: 0;
530
+ animation: shimmer 1.5s ease-in-out infinite;
531
+ }
532
+
533
+ .skeleton-text {
534
+ flex: 1;
535
+ display: flex;
536
+ flex-direction: column;
537
+ gap: 6px;
538
+ }
539
+
540
+ .skeleton-name {
541
+ height: 14px;
542
+ border-radius: 6px;
543
+ background: #f1f5f9;
544
+ animation: shimmer 1.5s ease-in-out infinite;
545
+ }
546
+
547
+ .skeleton-size {
548
+ height: 11px;
549
+ width: 60px;
550
+ border-radius: 6px;
551
+ background: #f1f5f9;
552
+ animation: shimmer 1.5s ease-in-out infinite;
553
+ }
554
+
555
+ .skeleton-row:nth-child(1) .skeleton-name { width: 65%; animation-delay: 0s; }
556
+ .skeleton-row:nth-child(1) .skeleton-thumb { animation-delay: 0s; }
557
+ .skeleton-row:nth-child(2) .skeleton-name { width: 45%; animation-delay: 0.1s; }
558
+ .skeleton-row:nth-child(2) .skeleton-thumb { animation-delay: 0.1s; }
559
+ .skeleton-row:nth-child(3) .skeleton-name { width: 75%; animation-delay: 0.2s; }
560
+ .skeleton-row:nth-child(3) .skeleton-thumb { animation-delay: 0.2s; }
561
+ .skeleton-row:nth-child(4) .skeleton-name { width: 55%; animation-delay: 0.3s; }
562
+ .skeleton-row:nth-child(4) .skeleton-thumb { animation-delay: 0.3s; }
563
+ .skeleton-row:nth-child(5) .skeleton-name { width: 60%; animation-delay: 0.4s; }
564
+ .skeleton-row:nth-child(5) .skeleton-thumb { animation-delay: 0.4s; }
565
+ .skeleton-row:nth-child(6) .skeleton-name { width: 50%; animation-delay: 0.5s; }
566
+ .skeleton-row:nth-child(6) .skeleton-thumb { animation-delay: 0.5s; }
567
+
568
+ @keyframes shimmer {
569
+ 0%, 100% { opacity: 1; }
570
+ 50% { opacity: 0.4; }
571
+ }
572
+
573
+ @keyframes spin {
574
+ to { transform: rotate(360deg); }
575
+ }
576
+
577
+ @media (prefers-reduced-motion: reduce) {
578
+ .spinner { animation: none; }
579
+ .skeleton-thumb, .skeleton-name, .skeleton-size { animation: none; }
580
+ }
581
+ `;let a=m;d([l.property({type:String})],a.prototype,"provider");d([l.property({type:String})],a.prototype,"companionUrl");d([l.state()],a.prototype,"_authenticated");d([l.state()],a.prototype,"_loading");d([l.state()],a.prototype,"_items");d([l.state()],a.prototype,"_selectedIds");d([l.state()],a.prototype,"_breadcrumbs");d([l.state()],a.prototype,"_nextPagePath");d([l.state()],a.prototype,"_error");d([l.state()],a.prototype,"_loadingMore");d([l.state()],a.prototype,"_username");function y(o){if(o===0)return"0 B";const e=["B","KB","MB","GB"],i=Math.min(Math.floor(Math.log(o)/Math.log(1024)),e.length-1);return`${(o/Math.pow(1024,i)).toFixed(i===0?0:1)} ${e[i]}`}exports.SfxProviderBrowser=a;
package/dist/react.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react");typeof customElements<"u"&&Promise.resolve().then(()=>require("./define.cjs"));const A=s.forwardRef(function({config:j,open:b,onFileAdded:q,onFileRemoved:U,onFileRejected:w,onUploadStarted:H,onUploadProgress:I,onUploadComplete:M,onUploadError:S,onUploadRetry:k,onAllComplete:z,onTotalProgress:B,onOpen:D,onClose:G,onCancel:J,className:_,style:$},F){const u=s.useRef(null),a=s.useRef(q),o=s.useRef(U),f=s.useRef(w),i=s.useRef(H),v=s.useRef(I),p=s.useRef(M),E=s.useRef(S),L=s.useRef(k),x=s.useRef(z),m=s.useRef(B),h=s.useRef(D),g=s.useRef(G),y=s.useRef(J);return s.useLayoutEffect(()=>{a.current=q,o.current=U,f.current=w,i.current=H,v.current=I,p.current=M,E.current=S,L.current=k,x.current=z,m.current=B,h.current=D,g.current=G,y.current=J}),s.useImperativeHandle(F,()=>({get element(){return u.current},open(){var e;(e=u.current)==null||e.open()},close(){var e;(e=u.current)==null||e.close()},upload(){var e;(e=u.current)==null||e.upload()},addFiles(e){var d;(d=u.current)==null||d.addFiles(e)},resumeUpload(e){var d;(d=u.current)==null||d.resumeUpload(e)},cancelUpload(){var e;(e=u.current)==null||e.cancelUpload()}})),s.useLayoutEffect(()=>{const e=u.current;e&&(e.config=j)},[j]),s.useEffect(()=>{const e=u.current;e&&(b===!0?e.open():b===!1&&e.close())},[b]),s.useEffect(()=>{const e=u.current;if(!e)return;const d=t=>{var r;const{file:n}=t.detail;(r=a.current)==null||r.call(a,n)},K=t=>{var r;const{file:n}=t.detail;(r=o.current)==null||r.call(o,n)},N=t=>{var c;const{file:n,reason:r}=t.detail;(c=f.current)==null||c.call(f,n,r)},O=t=>{var r;const{files:n}=t.detail;(r=i.current)==null||r.call(i,n)},P=t=>{var l;const{file:n,progress:r,speed:c}=t.detail;(l=v.current)==null||l.call(v,n,r,c)},Q=t=>{var c;const{file:n,response:r}=t.detail;(c=p.current)==null||c.call(p,n,r)},R=t=>{var c;const{file:n,error:r}=t.detail;(c=E.current)==null||c.call(E,n,r)},T=t=>{var c;const{successful:n,failed:r}=t.detail;(c=x.current)==null||c.call(x,n,r)},V=t=>{var c;const{file:n,attempt:r}=t.detail;(c=L.current)==null||c.call(L,n,r)},W=t=>{var l;const{percentage:n,speed:r,eta:c}=t.detail;(l=m.current)==null||l.call(m,n,r,c)},X=()=>{var t;(t=h.current)==null||t.call(h)},Y=()=>{var t;(t=g.current)==null||t.call(g)},Z=()=>{var t;(t=y.current)==null||t.call(y)};return e.addEventListener("sfx-file-added",d),e.addEventListener("sfx-file-removed",K),e.addEventListener("sfx-file-rejected",N),e.addEventListener("sfx-upload-started",O),e.addEventListener("sfx-upload-progress",P),e.addEventListener("sfx-upload-complete",Q),e.addEventListener("sfx-upload-error",R),e.addEventListener("sfx-upload-retry",V),e.addEventListener("sfx-all-complete",T),e.addEventListener("sfx-total-progress",W),e.addEventListener("sfx-open",X),e.addEventListener("sfx-close",Y),e.addEventListener("sfx-cancel",Z),()=>{e.removeEventListener("sfx-file-added",d),e.removeEventListener("sfx-file-removed",K),e.removeEventListener("sfx-file-rejected",N),e.removeEventListener("sfx-upload-started",O),e.removeEventListener("sfx-upload-progress",P),e.removeEventListener("sfx-upload-complete",Q),e.removeEventListener("sfx-upload-error",R),e.removeEventListener("sfx-upload-retry",V),e.removeEventListener("sfx-all-complete",T),e.removeEventListener("sfx-total-progress",W),e.removeEventListener("sfx-open",X),e.removeEventListener("sfx-close",Y),e.removeEventListener("sfx-cancel",Z)}},[]),s.createElement("sfx-uploader",{ref:u,className:_,style:$})});exports.Uploader=A;
@@ -0,0 +1,33 @@
1
+ import { CSSProperties } from 'react';
2
+ import { SfxUploader as SfxUploaderElement, UploaderConfig } from './sfx-uploader';
3
+ import { UploadFile, UploadResponse } from './store/store.types';
4
+ export interface UploaderRef {
5
+ element: SfxUploaderElement | null;
6
+ open(): void;
7
+ close(): void;
8
+ upload(): void;
9
+ addFiles(files: File[]): void;
10
+ resumeUpload(files?: UploadFile[]): void;
11
+ cancelUpload(): void;
12
+ }
13
+ export interface UploaderProps {
14
+ config: UploaderConfig;
15
+ open?: boolean;
16
+ onFileAdded?: (file: UploadFile) => void;
17
+ onFileRemoved?: (file: UploadFile) => void;
18
+ onFileRejected?: (file: UploadFile, reason: string) => void;
19
+ onUploadStarted?: (files: UploadFile[]) => void;
20
+ onUploadProgress?: (file: UploadFile, progress: number, speed: number) => void;
21
+ onUploadComplete?: (file: UploadFile, response: UploadResponse) => void;
22
+ onUploadError?: (file: UploadFile, error: Error) => void;
23
+ onUploadRetry?: (file: UploadFile, attempt: number) => void;
24
+ onAllComplete?: (successful: UploadFile[], failed: UploadFile[]) => void;
25
+ onTotalProgress?: (percentage: number, speed: number, eta: number) => void;
26
+ onOpen?: () => void;
27
+ onClose?: () => void;
28
+ onCancel?: () => void;
29
+ className?: string;
30
+ style?: CSSProperties;
31
+ }
32
+ export declare const Uploader: import('react').ForwardRefExoticComponent<UploaderProps & import('react').RefAttributes<UploaderRef>>;
33
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,WAAW,IAAI,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAOtE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAC9B,YAAY,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACzC,YAAY,IAAI,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IAChD,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/E,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACxE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACzD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IACzE,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,QAAQ,uGA6LpB,CAAC"}