@scaleflex/uploader 0.1.0 → 0.2.1

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 (60) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +1 -1
  3. package/dist/auth/auth.service.d.ts +1 -1
  4. package/dist/auth/auth.types.d.ts +1 -9
  5. package/dist/auth/auth.types.d.ts.map +1 -1
  6. package/dist/auth/index.d.ts +1 -1
  7. package/dist/auth/index.d.ts.map +1 -1
  8. package/dist/components/actions-bar.d.ts +4 -1
  9. package/dist/components/actions-bar.d.ts.map +1 -1
  10. package/dist/components/camera-dialog.d.ts +2 -1
  11. package/dist/components/camera-dialog.d.ts.map +1 -1
  12. package/dist/components/drop-zone.d.ts +17 -0
  13. package/dist/components/drop-zone.d.ts.map +1 -1
  14. package/dist/components/file-item.d.ts.map +1 -1
  15. package/dist/components/file-list.d.ts.map +1 -1
  16. package/dist/components/provider-browser.d.ts +1 -0
  17. package/dist/components/provider-browser.d.ts.map +1 -1
  18. package/dist/components/screen-cast-dialog.d.ts +2 -1
  19. package/dist/components/screen-cast-dialog.d.ts.map +1 -1
  20. package/dist/components/shared-styles.d.ts +5 -0
  21. package/dist/components/shared-styles.d.ts.map +1 -0
  22. package/dist/components/source-pills.d.ts.map +1 -1
  23. package/dist/components/success-card.d.ts +3 -1
  24. package/dist/components/success-card.d.ts.map +1 -1
  25. package/dist/components/url-dialog.d.ts +2 -2
  26. package/dist/components/url-dialog.d.ts.map +1 -1
  27. package/dist/connectors/provider-registry.d.ts.map +1 -1
  28. package/dist/define.cjs +1 -1
  29. package/dist/define.js +1 -1
  30. package/dist/engine/upload-engine.d.ts.map +1 -1
  31. package/dist/events/public-events.d.ts +1 -3
  32. package/dist/events/public-events.d.ts.map +1 -1
  33. package/dist/index.cjs +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -1
  37. package/dist/{provider-browser-C-S_MPrC.js → provider-browser-ixqCA0XP.js} +430 -185
  38. package/dist/provider-browser-yW3pZFSP.cjs +820 -0
  39. package/dist/{search-provider-browser-jCOer2Y9.js → search-provider-browser-B5ZWGUl8.js} +30 -30
  40. package/dist/{search-provider-browser-DxmLznEB.cjs → search-provider-browser-BrKVwGf_.cjs} +29 -29
  41. package/dist/sfx-uploader-CU9IwNC7.js +5384 -0
  42. package/dist/sfx-uploader-ziRTzw0k.cjs +3298 -0
  43. package/dist/sfx-uploader.d.ts +55 -1
  44. package/dist/sfx-uploader.d.ts.map +1 -1
  45. package/dist/store/store.types.d.ts +1 -1
  46. package/dist/store/store.types.d.ts.map +1 -1
  47. package/dist/types/source.types.d.ts +3 -0
  48. package/dist/types/source.types.d.ts.map +1 -1
  49. package/dist/utils/file-utils.d.ts +2 -0
  50. package/dist/utils/file-utils.d.ts.map +1 -1
  51. package/dist/utils/focus-trap.d.ts +7 -0
  52. package/dist/utils/focus-trap.d.ts.map +1 -0
  53. package/dist/utils/validate.d.ts +11 -0
  54. package/dist/utils/validate.d.ts.map +1 -1
  55. package/package.json +4 -2
  56. package/dist/events/event-bus.d.ts +0 -38
  57. package/dist/events/event-bus.d.ts.map +0 -1
  58. package/dist/provider-browser-CmCwv0ph.cjs +0 -581
  59. package/dist/sfx-uploader-BVDK-9xi.cjs +0 -2029
  60. package/dist/sfx-uploader-C2lWIRnU.js +0 -3789
@@ -0,0 +1,820 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("lit"),l=require("lit/decorators.js"),b=require("lit/directives/unsafe-html.js"),c=require("./sfx-uploader-ziRTzw0k.cjs"),x="sfx-uploader-token:";function p(o){try{return localStorage.getItem(`${x}${o}`)}catch{return null}}function v(o,e){try{localStorage.setItem(`${x}${o}`,e)}catch{}}function u(o){try{localStorage.removeItem(`${x}${o}`)}catch{}}function k(o,e){const r=i=>{if(i.origin!==new URL(o).origin)return;const t=typeof i.data=="string"?y(i.data):i.data;t!=null&&t.token&&e(t.token)};return window.addEventListener("message",r),()=>window.removeEventListener("message",r)}function y(o){try{return JSON.parse(o)}catch{return null}}var _=Object.defineProperty,d=(o,e,r,i)=>{for(var t=void 0,n=o.length-1,h;n>=0;n--)(h=o[n])&&(t=h(e,r,t)||t);return t&&_(e,r,t),t};const g=class g 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 r;const e=c.getAuthUrl(this.companionUrl,this.provider);this._authWindow=window.open(e,"_blank","width=600,height=600"),(r=this._cleanupAuthListener)==null||r.call(this),this._cleanupAuthListener=k(this.companionUrl,i=>{var t,n;(t=this._authWindow)==null||t.close(),this._authWindow=null,(n=this._cleanupAuthListener)==null||n.call(this),this._cleanupAuthListener=null,v(this.provider,i),this._authenticated=!0,this._loadFolder("")})},this._lastClickedIndex=null,this._toggleSelectAll=()=>{const e=this._items.filter(i=>!i.isFolder);e.every(i=>this._selectedIds.has(i.id))?this._selectedIds=new Set:this._selectedIds=new Set(e.map(i=>i.id))},this._onAddSelected=()=>{const e=p(this.provider);if(!e)return;const i=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:i},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{}u(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 _providerDef(){return c.getProviderSources([this.provider])[0]??null}get _providerLabel(){var e;return((e=this._providerDef)==null?void 0:e.label)??this.provider}async _loadFolder(e){const r=p(this.provider);if(!r){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 i=await c.listFiles(this.companionUrl,this.provider,r,e);this._items=i.items,this._nextPagePath=i.nextPagePath,i.username&&(this._username=i.username)}catch(i){i instanceof c.AuthExpiredError?(u(this.provider),this._authenticated=!1):this._error=i instanceof Error?i.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 r=this._breadcrumbs[e];this._breadcrumbs=this._breadcrumbs.slice(0,e+1),this._loadFolder(r.path)}}async _onLoadMore(){const e=p(this.provider);if(!(!e||!this._nextPagePath)){this._loadingMore=!0;try{const r=await c.listNextPage(this.companionUrl,e,this._nextPagePath);this._items=[...this._items,...r.items],this._nextPagePath=r.nextPagePath}catch(r){r instanceof c.AuthExpiredError&&(u(this.provider),this._authenticated=!1)}finally{this._loadingMore=!1}}}_toggleSelect(e,r){const i=this._items.filter(n=>!n.isFolder),t=i.findIndex(n=>n.id===e.id);if(r!=null&&r.shiftKey&&this._lastClickedIndex!==null&&t!==-1){const n=Math.min(this._lastClickedIndex,t),h=Math.max(this._lastClickedIndex,t),m=new Set(this._selectedIds);for(let f=n;f<=h;f++)m.add(i[f].id);this._selectedIds=m}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(){const e=this._providerDef;return s.html`
5
+ <div class="browser-header">
6
+ <button class="back-btn" @click=${this._onClose} title="Back">
7
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
8
+ <polyline points="15 18 9 12 15 6" />
9
+ </svg>
10
+ </button>
11
+ <div class="header-brand">
12
+ ${e!=null&&e.brandHtml?s.html`<div class="header-logo">${b.unsafeHTML(e.brandHtml)}</div>`:s.nothing}
13
+
14
+ <div class="header-title-group">
15
+ <span class="browser-title">${this._providerLabel}</span>
16
+ ${this._authenticated&&this._username?s.html`<span class="header-username">${this._username}</span>`:s.nothing}
17
+ </div>
18
+ </div>
19
+ ${this._authenticated?s.html`<button class="logout-btn" @click=${this._handleLogout}>Sign out</button>`:s.nothing}
20
+ </div>
21
+ `}_renderAuthView(){const e=this._providerDef;return s.html`
22
+ <div class="auth-view">
23
+ <div class="auth-glow"></div>
24
+ <div class="auth-logo-wrap">
25
+ <div class="auth-ring">
26
+ <div class="auth-logo">
27
+ ${e!=null&&e.brandHtml?s.html`<span style="display:flex;align-items:center;justify-content:center;transform:scale(2.2)">${b.unsafeHTML(e.brandHtml)}</span>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="var(--sfx-up-primary, #2563eb)" stroke-width="1.5"><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="var(--sfx-up-primary, #2563eb)"/></svg>`}
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <div class="auth-content">
32
+ <div class="auth-title">Connect ${this._providerLabel}</div>
33
+ <div class="auth-text">
34
+ Sign in to browse and select files from your ${this._providerLabel} account
35
+ </div>
36
+ </div>
37
+ <button class="connect-btn" @click=${this._handleConnect}>
38
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
39
+ <path d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4M10 17l5-5-5-5M15 12H3"/>
40
+ </svg>
41
+ Sign in to ${this._providerLabel}
42
+ </button>
43
+ </div>
44
+ `}_renderLoading(){const e=[1,2,3,4,5,6,7];return s.html`
45
+ <div class="skeleton-list">
46
+ ${e.map(()=>s.html`
47
+ <div class="skeleton-row">
48
+ <div class="skeleton-check"></div>
49
+ <div class="skeleton-thumb"></div>
50
+ <div class="skeleton-text">
51
+ <div class="skeleton-name"></div>
52
+ <div class="skeleton-size"></div>
53
+ </div>
54
+ </div>
55
+ `)}
56
+ </div>
57
+ `}_renderError(){return s.html`
58
+ <div class="error-view">
59
+ <div class="error-icon">
60
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
61
+ <circle cx="12" cy="12" r="10" />
62
+ <line x1="15" y1="9" x2="9" y2="15" />
63
+ <line x1="9" y1="9" x2="15" y2="15" />
64
+ </svg>
65
+ </div>
66
+ <div class="error-text">${this._error}</div>
67
+ <button class="retry-btn" @click=${()=>{const e=this._breadcrumbs[this._breadcrumbs.length-1];this._loadFolder((e==null?void 0:e.path)??"")}}>
68
+ Try again
69
+ </button>
70
+ </div>
71
+ `}_renderBrowser(){const e=this._items.filter(t=>!t.isFolder),r=this._items.filter(t=>t.isFolder),i=this._selectedIds.size;return s.html`
72
+ ${this._renderBreadcrumbs()}
73
+
74
+ <div class="file-list">
75
+ ${r.length===0&&e.length===0?s.html`
76
+ <div class="empty-state">
77
+ <div class="empty-icon">
78
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
79
+ <path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" />
80
+ <line x1="9" y1="14" x2="15" y2="14" />
81
+ </svg>
82
+ </div>
83
+ <div class="empty-text">This folder is empty</div>
84
+ </div>
85
+ `:s.nothing}
86
+
87
+ ${r.map(t=>s.html`
88
+ <div class="file-item" @click=${()=>this._onFolderClick(t)}>
89
+ <div class="file-thumb folder-thumb">
90
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
91
+ <path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" />
92
+ </svg>
93
+ </div>
94
+ <div class="file-info">
95
+ <div class="file-name">${t.name}</div>
96
+ </div>
97
+ <svg class="folder-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
98
+ <polyline points="9 18 15 12 9 6" />
99
+ </svg>
100
+ </div>
101
+ `)}
102
+
103
+ ${e.map(t=>s.html`
104
+ <div
105
+ class="file-item ${this._selectedIds.has(t.id)?"selected":""}"
106
+ @click=${n=>this._toggleSelect(t,n)}
107
+ >
108
+ <input
109
+ type="checkbox"
110
+ .checked=${this._selectedIds.has(t.id)}
111
+ @click=${n=>n.stopPropagation()}
112
+ @change=${()=>this._toggleSelect(t)}
113
+ />
114
+ <div class="file-thumb">
115
+ ${t.thumbnail?s.html`<img src=${t.thumbnail} alt="" loading="lazy" referrerpolicy="no-referrer"
116
+ @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>'}}
117
+ />`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
118
+ <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
119
+ <polyline points="14 2 14 8 20 8" />
120
+ </svg>`}
121
+ </div>
122
+ <div class="file-info">
123
+ <div class="file-name">${t.name}</div>
124
+ <div class="file-meta">
125
+ ${t.size?s.html`<span class="file-size">${w(t.size)}</span>`:s.nothing}
126
+ </div>
127
+ </div>
128
+ </div>
129
+ `)}
130
+
131
+ ${this._nextPagePath?s.html`
132
+ <button
133
+ class="load-more-btn"
134
+ ?disabled=${this._loadingMore}
135
+ @click=${this._onLoadMore}
136
+ >
137
+ ${this._loadingMore?"Loading...":"Load more"}
138
+ </button>
139
+ `:s.nothing}
140
+ </div>
141
+
142
+ ${e.length>0||i>0?s.html`
143
+ <div class="browser-footer">
144
+ <div class="footer-left">
145
+ <button class="select-all-btn" @click=${this._toggleSelectAll}>
146
+ ${e.every(t=>this._selectedIds.has(t.id))?"Deselect all":"Select all"}
147
+ </button>
148
+ <span class="selected-count ${i>0?"has-selection":""}">
149
+ ${i>0?`${i} file${i===1?"":"s"} selected`:"No files selected"}
150
+ </span>
151
+ </div>
152
+ <button
153
+ class="add-btn"
154
+ ?disabled=${i===0}
155
+ @click=${this._onAddSelected}
156
+ >
157
+ Add${i>0?` ${i}`:""} file${i===1?"":"s"}
158
+ </button>
159
+ </div>
160
+ `:s.nothing}
161
+ `}_renderBreadcrumbs(){return this._breadcrumbs.length===0?s.nothing:s.html`
162
+ <div class="breadcrumbs">
163
+ <button class="crumb" @click=${()=>this._onBreadcrumbClick(-1)}>
164
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="width:12px;height:12px;vertical-align:middle;margin-right:2px">
165
+ <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
166
+ </svg>
167
+ Root
168
+ </button>
169
+ ${this._breadcrumbs.map((e,r)=>s.html`
170
+ <span class="crumb-sep">&rsaquo;</span>
171
+ ${r<this._breadcrumbs.length-1?s.html`<button class="crumb" @click=${()=>this._onBreadcrumbClick(r)}>${e.name}</button>`:s.html`<span class="crumb-current">${e.name}</span>`}
172
+ `)}
173
+ </div>
174
+ `}};g.styles=s.css`
175
+ :host {
176
+ display: flex;
177
+ flex-direction: column;
178
+ height: 100%;
179
+ min-height: 300px;
180
+ font-family: var(--sfx-up-font, 'Inter', system-ui, -apple-system, sans-serif);
181
+ color: var(--sfx-up-text, #1e293b);
182
+ background: var(--sfx-up-bg, #fff);
183
+ }
184
+
185
+ /* --- Header --- */
186
+ .browser-header {
187
+ display: flex;
188
+ align-items: center;
189
+ gap: 12px;
190
+ padding: 14px 20px;
191
+ border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
192
+ flex-shrink: 0;
193
+ }
194
+
195
+ .back-btn {
196
+ width: 32px;
197
+ height: 32px;
198
+ border: none;
199
+ background: var(--sfx-up-border-light, #f1f5f9);
200
+ border-radius: 8px;
201
+ cursor: pointer;
202
+ display: flex;
203
+ align-items: center;
204
+ justify-content: center;
205
+ color: var(--sfx-up-text-secondary, #475569);
206
+ transition: all 0.15s;
207
+ flex-shrink: 0;
208
+ }
209
+
210
+ .back-btn:hover {
211
+ background: var(--sfx-up-border, #e8edf5);
212
+ color: var(--sfx-up-text, #1e293b);
213
+ }
214
+
215
+ .back-btn svg {
216
+ width: 16px;
217
+ height: 16px;
218
+ }
219
+
220
+ .header-brand {
221
+ display: flex;
222
+ align-items: center;
223
+ gap: 10px;
224
+ flex: 1;
225
+ min-width: 0;
226
+ }
227
+
228
+ .header-logo {
229
+ width: 28px;
230
+ height: 28px;
231
+ border-radius: 7px;
232
+ display: flex;
233
+ align-items: center;
234
+ justify-content: center;
235
+ flex-shrink: 0;
236
+ overflow: hidden;
237
+ }
238
+
239
+ .header-logo svg {
240
+ width: 20px;
241
+ height: 20px;
242
+ }
243
+
244
+ .header-title-group {
245
+ display: flex;
246
+ flex-direction: column;
247
+ min-width: 0;
248
+ }
249
+
250
+ .browser-title {
251
+ font-size: 14px;
252
+ font-weight: 600;
253
+ line-height: 1.2;
254
+ }
255
+
256
+ .header-username {
257
+ font-size: 11px;
258
+ color: var(--sfx-up-text-muted, #94a3b8);
259
+ white-space: nowrap;
260
+ overflow: hidden;
261
+ text-overflow: ellipsis;
262
+ }
263
+
264
+ .logout-btn {
265
+ border: 1px solid var(--sfx-up-border, #e8edf5);
266
+ background: none;
267
+ font-family: inherit;
268
+ font-size: 12px;
269
+ font-weight: 500;
270
+ color: var(--sfx-up-text-muted, #94a3b8);
271
+ cursor: pointer;
272
+ padding: 5px 10px;
273
+ border-radius: 6px;
274
+ transition: all 0.15s;
275
+ flex-shrink: 0;
276
+ }
277
+
278
+ .logout-btn:hover {
279
+ background: var(--destructive-10, #fef2f2);
280
+ color: var(--sfx-up-error, #dc2626);
281
+ border-color: #fecaca;
282
+ }
283
+
284
+ /* --- Auth view --- */
285
+ .auth-view {
286
+ flex: 1;
287
+ display: flex;
288
+ flex-direction: column;
289
+ align-items: center;
290
+ justify-content: center;
291
+ gap: 20px;
292
+ padding: 40px 32px;
293
+ text-align: center;
294
+ position: relative;
295
+ overflow: hidden;
296
+ }
297
+
298
+ .auth-glow {
299
+ position: absolute;
300
+ width: 280px;
301
+ height: 280px;
302
+ border-radius: 50%;
303
+ background: radial-gradient(circle, var(--sfx-up-primary-bg, #eff6ff) 0%, transparent 70%);
304
+ opacity: 0.7;
305
+ pointer-events: none;
306
+ }
307
+
308
+ .auth-logo-wrap {
309
+ position: relative;
310
+ z-index: 1;
311
+ }
312
+
313
+ .auth-ring {
314
+ width: 100px;
315
+ height: 100px;
316
+ border-radius: 50%;
317
+ border: 1.5px dashed var(--sfx-up-border, #e8edf5);
318
+ display: flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ animation: slowSpin 20s linear infinite;
322
+ }
323
+
324
+ .auth-logo {
325
+ width: 64px;
326
+ height: 64px;
327
+ border-radius: 18px;
328
+ background: #fff;
329
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.04);
330
+ display: flex;
331
+ align-items: center;
332
+ justify-content: center;
333
+ animation: slowSpin 20s linear infinite reverse;
334
+ }
335
+
336
+ .auth-logo svg {
337
+ width: 34px;
338
+ height: 34px;
339
+ }
340
+
341
+ .auth-content {
342
+ position: relative;
343
+ z-index: 1;
344
+ display: flex;
345
+ flex-direction: column;
346
+ align-items: center;
347
+ gap: 8px;
348
+ }
349
+
350
+ .auth-title {
351
+ font-size: 16px;
352
+ font-weight: 700;
353
+ color: var(--sfx-up-text, #1e293b);
354
+ }
355
+
356
+ .auth-text {
357
+ font-size: 13px;
358
+ color: var(--sfx-up-text-muted, #94a3b8);
359
+ max-width: 260px;
360
+ line-height: 1.5;
361
+ }
362
+
363
+ .connect-btn {
364
+ position: relative;
365
+ z-index: 1;
366
+ height: 42px;
367
+ padding: 0 28px;
368
+ border: none;
369
+ border-radius: 11px;
370
+ background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
371
+ color: var(--primary-foreground, #fff);
372
+ font-family: inherit;
373
+ font-size: 14px;
374
+ font-weight: 600;
375
+ cursor: pointer;
376
+ transition: all 0.2s;
377
+ box-shadow: 0 4px 16px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.25));
378
+ display: flex;
379
+ align-items: center;
380
+ gap: 8px;
381
+ margin-top: 4px;
382
+ }
383
+
384
+ .connect-btn:hover {
385
+ transform: translateY(-1px);
386
+ box-shadow: 0 6px 24px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.35));
387
+ }
388
+
389
+ .connect-btn:active {
390
+ transform: translateY(0);
391
+ }
392
+
393
+ .connect-btn svg {
394
+ width: 16px;
395
+ height: 16px;
396
+ }
397
+
398
+ /* --- Breadcrumbs --- */
399
+ .breadcrumbs {
400
+ display: flex;
401
+ align-items: center;
402
+ gap: 2px;
403
+ padding: 8px 20px;
404
+ font-size: 12px;
405
+ color: var(--sfx-up-text-muted, #94a3b8);
406
+ border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
407
+ flex-shrink: 0;
408
+ flex-wrap: wrap;
409
+ background: var(--sfx-up-border-light, #fafbfd);
410
+ }
411
+
412
+ .crumb {
413
+ cursor: pointer;
414
+ color: var(--sfx-up-primary, #2563eb);
415
+ border: none;
416
+ background: none;
417
+ font-family: inherit;
418
+ font-size: 12px;
419
+ padding: 3px 6px;
420
+ border-radius: 5px;
421
+ transition: background 0.15s;
422
+ font-weight: 500;
423
+ }
424
+
425
+ .crumb:hover {
426
+ background: var(--sfx-up-primary-bg, #eff6ff);
427
+ }
428
+
429
+ .crumb-sep {
430
+ color: var(--sfx-up-text-muted, #94a3b8);
431
+ font-size: 10px;
432
+ }
433
+
434
+ .crumb-current {
435
+ color: var(--sfx-up-text, #1e293b);
436
+ font-weight: 600;
437
+ padding: 3px 6px;
438
+ font-size: 12px;
439
+ }
440
+
441
+ /* --- File list --- */
442
+ .file-list {
443
+ flex: 1;
444
+ overflow-y: auto;
445
+ padding: 6px 8px;
446
+ min-height: 0;
447
+ }
448
+
449
+ .file-item {
450
+ display: flex;
451
+ align-items: center;
452
+ gap: 12px;
453
+ padding: 8px 12px;
454
+ border-radius: 10px;
455
+ cursor: pointer;
456
+ transition: all 0.15s;
457
+ user-select: none;
458
+ border: 1.5px solid transparent;
459
+ }
460
+
461
+ .file-item:hover {
462
+ background: var(--sfx-up-border-light, #f8fafc);
463
+ }
464
+
465
+ .file-item.selected {
466
+ background: var(--sfx-up-primary-bg, #eff6ff);
467
+ border-color: var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.15));
468
+ }
469
+
470
+ .file-item input[type='checkbox'] {
471
+ width: 16px;
472
+ height: 16px;
473
+ accent-color: var(--sfx-up-primary, #2563eb);
474
+ flex-shrink: 0;
475
+ cursor: pointer;
476
+ }
477
+
478
+ .file-thumb {
479
+ width: 38px;
480
+ height: 38px;
481
+ border-radius: 8px;
482
+ background: var(--sfx-up-border-light, #f1f5f9);
483
+ display: flex;
484
+ align-items: center;
485
+ justify-content: center;
486
+ flex-shrink: 0;
487
+ overflow: hidden;
488
+ }
489
+
490
+ .file-thumb img {
491
+ width: 100%;
492
+ height: 100%;
493
+ object-fit: cover;
494
+ }
495
+
496
+ .file-thumb svg {
497
+ width: 18px;
498
+ height: 18px;
499
+ color: var(--sfx-up-text-muted, #94a3b8);
500
+ }
501
+
502
+ .file-thumb.folder-thumb {
503
+ background: linear-gradient(135deg, #fef3c7, #fde68a);
504
+ }
505
+
506
+ .file-thumb.folder-thumb svg {
507
+ color: #d97706;
508
+ }
509
+
510
+ .file-info {
511
+ flex: 1;
512
+ min-width: 0;
513
+ }
514
+
515
+ .file-name {
516
+ font-size: 13px;
517
+ font-weight: 500;
518
+ white-space: nowrap;
519
+ overflow: hidden;
520
+ text-overflow: ellipsis;
521
+ }
522
+
523
+ .file-meta {
524
+ display: flex;
525
+ align-items: center;
526
+ gap: 6px;
527
+ }
528
+
529
+ .file-size {
530
+ font-size: 11px;
531
+ color: var(--sfx-up-text-muted, #94a3b8);
532
+ }
533
+
534
+ .folder-arrow {
535
+ width: 16px;
536
+ height: 16px;
537
+ color: var(--sfx-up-text-muted, #94a3b8);
538
+ flex-shrink: 0;
539
+ opacity: 0;
540
+ transition: opacity 0.15s;
541
+ }
542
+
543
+ .file-item:hover .folder-arrow {
544
+ opacity: 1;
545
+ }
546
+
547
+ /* --- Footer --- */
548
+ .browser-footer {
549
+ display: flex;
550
+ align-items: center;
551
+ justify-content: space-between;
552
+ padding: 12px 16px;
553
+ border-top: 1px solid var(--sfx-up-border-light, #f1f5f9);
554
+ flex-shrink: 0;
555
+ gap: 12px;
556
+ background: var(--sfx-up-bg, #fff);
557
+ }
558
+
559
+ .footer-left {
560
+ display: flex;
561
+ align-items: center;
562
+ gap: 8px;
563
+ }
564
+
565
+ .selected-count {
566
+ font-size: 12px;
567
+ color: var(--sfx-up-text-muted, #94a3b8);
568
+ font-weight: 500;
569
+ }
570
+
571
+ .selected-count.has-selection {
572
+ color: var(--sfx-up-primary, #2563eb);
573
+ }
574
+
575
+ .add-btn {
576
+ height: 36px;
577
+ padding: 0 20px;
578
+ border: none;
579
+ border-radius: 9px;
580
+ background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
581
+ color: var(--primary-foreground, #fff);
582
+ font-family: inherit;
583
+ font-size: 13px;
584
+ font-weight: 600;
585
+ cursor: pointer;
586
+ transition: all 0.18s;
587
+ box-shadow: 0 2px 10px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.28));
588
+ display: flex;
589
+ align-items: center;
590
+ gap: 6px;
591
+ }
592
+
593
+ .add-btn:hover:not(:disabled) {
594
+ transform: translateY(-1px);
595
+ box-shadow: 0 4px 16px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.38));
596
+ }
597
+
598
+ .add-btn:disabled {
599
+ opacity: 0.4;
600
+ cursor: not-allowed;
601
+ }
602
+
603
+ .select-all-btn {
604
+ border: 1px solid var(--sfx-up-border, #e8edf5);
605
+ background: none;
606
+ font-family: inherit;
607
+ font-size: 12px;
608
+ font-weight: 500;
609
+ color: var(--sfx-up-text-secondary, #475569);
610
+ cursor: pointer;
611
+ padding: 5px 10px;
612
+ border-radius: 6px;
613
+ transition: all 0.15s;
614
+ flex-shrink: 0;
615
+ }
616
+
617
+ .select-all-btn:hover {
618
+ background: var(--sfx-up-primary-bg, #eff6ff);
619
+ color: var(--sfx-up-primary, #2563eb);
620
+ border-color: var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.2));
621
+ }
622
+
623
+ /* --- Loading / Error --- */
624
+ .loading, .error-view, .empty-state {
625
+ flex: 1;
626
+ display: flex;
627
+ flex-direction: column;
628
+ align-items: center;
629
+ justify-content: center;
630
+ gap: 12px;
631
+ padding: 40px 24px;
632
+ text-align: center;
633
+ }
634
+
635
+ .spinner {
636
+ width: 28px;
637
+ height: 28px;
638
+ border: 3px solid var(--sfx-up-border, #e8edf5);
639
+ border-top-color: var(--sfx-up-primary, #2563eb);
640
+ border-radius: 50%;
641
+ animation: spin 0.7s linear infinite;
642
+ }
643
+
644
+ .error-icon {
645
+ width: 48px;
646
+ height: 48px;
647
+ border-radius: 14px;
648
+ background: #fef2f2;
649
+ display: flex;
650
+ align-items: center;
651
+ justify-content: center;
652
+ }
653
+
654
+ .error-icon svg {
655
+ width: 24px;
656
+ height: 24px;
657
+ color: var(--sfx-up-error, #dc2626);
658
+ }
659
+
660
+ .error-text {
661
+ font-size: 13px;
662
+ color: var(--sfx-up-text-secondary, #475569);
663
+ max-width: 260px;
664
+ line-height: 1.4;
665
+ }
666
+
667
+ .retry-btn {
668
+ height: 34px;
669
+ padding: 0 16px;
670
+ border: 1.5px solid var(--sfx-up-border, #e8edf5);
671
+ background: none;
672
+ border-radius: 8px;
673
+ font-family: inherit;
674
+ font-size: 13px;
675
+ font-weight: 600;
676
+ cursor: pointer;
677
+ color: var(--sfx-up-text-secondary, #475569);
678
+ transition: all 0.15s;
679
+ }
680
+
681
+ .retry-btn:hover {
682
+ background: var(--sfx-up-border-light, #f8faff);
683
+ border-color: var(--sfx-up-border, #d1dff0);
684
+ }
685
+
686
+ .load-more-btn {
687
+ display: block;
688
+ margin: 8px auto;
689
+ padding: 8px 20px;
690
+ border: 1.5px solid var(--sfx-up-border, #e8edf5);
691
+ background: none;
692
+ border-radius: 8px;
693
+ font-family: inherit;
694
+ font-size: 13px;
695
+ font-weight: 500;
696
+ cursor: pointer;
697
+ color: var(--sfx-up-primary, #2563eb);
698
+ transition: all 0.15s;
699
+ }
700
+
701
+ .load-more-btn:hover {
702
+ background: var(--sfx-up-primary-bg, #eff6ff);
703
+ }
704
+
705
+ .empty-icon {
706
+ width: 48px;
707
+ height: 48px;
708
+ border-radius: 14px;
709
+ background: var(--sfx-up-border-light, #f1f5f9);
710
+ display: flex;
711
+ align-items: center;
712
+ justify-content: center;
713
+ }
714
+
715
+ .empty-icon svg {
716
+ width: 24px;
717
+ height: 24px;
718
+ color: var(--sfx-up-text-muted, #94a3b8);
719
+ }
720
+
721
+ .empty-text {
722
+ font-size: 13px;
723
+ color: var(--sfx-up-text-muted, #94a3b8);
724
+ }
725
+
726
+ /* --- Skeleton loading --- */
727
+ .skeleton-list {
728
+ flex: 1;
729
+ padding: 6px 8px;
730
+ min-height: 0;
731
+ }
732
+
733
+ .skeleton-row {
734
+ display: flex;
735
+ align-items: center;
736
+ gap: 12px;
737
+ padding: 8px 12px;
738
+ }
739
+
740
+ .skeleton-check {
741
+ width: 16px;
742
+ height: 16px;
743
+ border-radius: 4px;
744
+ background: var(--sfx-up-border-light, #f1f5f9);
745
+ }
746
+
747
+ .skeleton-thumb {
748
+ width: 38px;
749
+ height: 38px;
750
+ border-radius: 8px;
751
+ background: var(--sfx-up-border-light, #f1f5f9);
752
+ flex-shrink: 0;
753
+ animation: shimmer 1.5s ease-in-out infinite;
754
+ }
755
+
756
+ .skeleton-text {
757
+ flex: 1;
758
+ display: flex;
759
+ flex-direction: column;
760
+ gap: 6px;
761
+ }
762
+
763
+ .skeleton-name {
764
+ height: 14px;
765
+ border-radius: 6px;
766
+ background: var(--sfx-up-border-light, #f1f5f9);
767
+ animation: shimmer 1.5s ease-in-out infinite;
768
+ }
769
+
770
+ .skeleton-size {
771
+ height: 11px;
772
+ width: 60px;
773
+ border-radius: 6px;
774
+ background: var(--sfx-up-border-light, #f1f5f9);
775
+ animation: shimmer 1.5s ease-in-out infinite;
776
+ }
777
+
778
+ .skeleton-row:nth-child(1) .skeleton-name { width: 65%; animation-delay: 0s; }
779
+ .skeleton-row:nth-child(1) .skeleton-thumb { animation-delay: 0s; }
780
+ .skeleton-row:nth-child(2) .skeleton-name { width: 45%; animation-delay: 0.1s; }
781
+ .skeleton-row:nth-child(2) .skeleton-thumb { animation-delay: 0.1s; }
782
+ .skeleton-row:nth-child(3) .skeleton-name { width: 75%; animation-delay: 0.2s; }
783
+ .skeleton-row:nth-child(3) .skeleton-thumb { animation-delay: 0.2s; }
784
+ .skeleton-row:nth-child(4) .skeleton-name { width: 55%; animation-delay: 0.3s; }
785
+ .skeleton-row:nth-child(4) .skeleton-thumb { animation-delay: 0.3s; }
786
+ .skeleton-row:nth-child(5) .skeleton-name { width: 60%; animation-delay: 0.4s; }
787
+ .skeleton-row:nth-child(5) .skeleton-thumb { animation-delay: 0.4s; }
788
+ .skeleton-row:nth-child(6) .skeleton-name { width: 50%; animation-delay: 0.5s; }
789
+ .skeleton-row:nth-child(6) .skeleton-thumb { animation-delay: 0.5s; }
790
+ .skeleton-row:nth-child(7) .skeleton-name { width: 70%; animation-delay: 0.6s; }
791
+ .skeleton-row:nth-child(7) .skeleton-thumb { animation-delay: 0.6s; }
792
+
793
+ @keyframes shimmer {
794
+ 0%, 100% { opacity: 1; }
795
+ 50% { opacity: 0.4; }
796
+ }
797
+
798
+ @keyframes spin {
799
+ to { transform: rotate(360deg); }
800
+ }
801
+
802
+ @keyframes slowSpin {
803
+ to { transform: rotate(360deg); }
804
+ }
805
+
806
+ @keyframes fadeUp {
807
+ from { opacity: 0; transform: translateY(10px); }
808
+ to { opacity: 1; transform: translateY(0); }
809
+ }
810
+
811
+ .auth-view { animation: fadeUp 0.35s ease both; }
812
+
813
+ @media (prefers-reduced-motion: reduce) {
814
+ .spinner { animation: none; }
815
+ .skeleton-thumb, .skeleton-name, .skeleton-size { animation: none; }
816
+ .auth-ring { animation: none; }
817
+ .auth-logo { animation: none; }
818
+ .auth-view { animation: none; }
819
+ }
820
+ `;let a=g;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 w(o){if(o===0)return"0 B";const e=["B","KB","MB","GB"],r=Math.min(Math.floor(Math.log(o)/Math.log(1024)),e.length-1);return`${(o/Math.pow(1024,r)).toFixed(r===0?0:1)} ${e[r]}`}exports.SfxProviderBrowser=a;