@scaleflex/asset-picker 0.2.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.
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/integrate-asset-picker/SKILL.md +391 -0
- package/README.md +43 -11
- package/dist/{asset-picker-CSsp_Huy.js → asset-picker-CCQPEvDB.js} +8 -18
- package/dist/{asset-picker-DBOWNXd-.cjs → asset-picker-DH2dd4M9.cjs} +81 -81
- package/dist/asset-picker.d.ts.map +1 -1
- package/dist/define.cjs +1 -1
- package/dist/define.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/services/api-client.d.ts +1 -0
- package/dist/services/api-client.d.ts.map +1 -1
- package/dist/types/config.types.d.ts +7 -8
- package/dist/types/config.types.d.ts.map +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(ls:*)",
|
|
5
|
+
"Bash(grep:*)",
|
|
6
|
+
"Bash(npm install:*)",
|
|
7
|
+
"Bash(npx tsc:*)",
|
|
8
|
+
"Bash(npx vite:*)",
|
|
9
|
+
"WebFetch(domain:localhost)",
|
|
10
|
+
"Bash(curl:*)",
|
|
11
|
+
"Bash(node:*)",
|
|
12
|
+
"WebSearch",
|
|
13
|
+
"Bash(npm run:*)",
|
|
14
|
+
"Bash(wc:*)",
|
|
15
|
+
"WebFetch(domain:unpkg.com)",
|
|
16
|
+
"Bash(git:*)",
|
|
17
|
+
"Bash(find /Users/dmitrystremous/scaleflex -maxdepth 3 -type d -name \"*admin*\" 2>/dev/null | grep -i filerobot)",
|
|
18
|
+
"Bash(gh run:*)",
|
|
19
|
+
"Bash(gh workflow:*)",
|
|
20
|
+
"Bash(find:*)",
|
|
21
|
+
"Bash(npx playwright:*)",
|
|
22
|
+
"Bash(npm ls:*)",
|
|
23
|
+
"Read(//Users/dmitrystremous/**)",
|
|
24
|
+
"Bash(npx:*)",
|
|
25
|
+
"Bash(rm:*)",
|
|
26
|
+
"Bash(tail:*)",
|
|
27
|
+
"WebFetch(domain:raw.githubusercontent.com)",
|
|
28
|
+
"Bash(gh api:*)",
|
|
29
|
+
"WebFetch(domain:www.scaleflex.com)",
|
|
30
|
+
"WebFetch(domain:scaleflex.github.io)",
|
|
31
|
+
"WebFetch(domain:github.com)",
|
|
32
|
+
"WebFetch(domain:portals.scaleflex.com)",
|
|
33
|
+
"Bash(for f:*)",
|
|
34
|
+
"Bash(do echo:*)",
|
|
35
|
+
"Read(//Users/dmitrystremous/scaleflex/asset-picker/**)",
|
|
36
|
+
"Bash(done)",
|
|
37
|
+
"Bash(cd:*)",
|
|
38
|
+
"Bash(chmod:*)",
|
|
39
|
+
"Bash(./scripts/publish-github.sh \"v0.1.0 — initial release\" 2>&1)",
|
|
40
|
+
"Bash(npm whoami:*)",
|
|
41
|
+
"Bash(npm publish:*)",
|
|
42
|
+
"Bash(gh repo:*)",
|
|
43
|
+
"Bash(./scripts/publish-github.sh \"Update README with demo and docs links\" 2>&1)",
|
|
44
|
+
"Bash(lsof:*)",
|
|
45
|
+
"Bash(kill:*)",
|
|
46
|
+
"Bash(npm view:*)"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: integrate-asset-picker
|
|
3
|
+
description: Integrate @scaleflex/asset-picker into any project — install, configure auth,
|
|
4
|
+
wire events, theme, and add filters. Works with vanilla JS, React, Vue, Angular, Svelte.
|
|
5
|
+
user_invocable: true
|
|
6
|
+
metadata:
|
|
7
|
+
category: integration
|
|
8
|
+
tags:
|
|
9
|
+
- scaleflex
|
|
10
|
+
- dam
|
|
11
|
+
- asset-picker
|
|
12
|
+
- web-component
|
|
13
|
+
status: ready
|
|
14
|
+
version: 1
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Scaleflex Asset Picker Integration Skill
|
|
18
|
+
|
|
19
|
+
## When to Use
|
|
20
|
+
|
|
21
|
+
- User says "add asset picker", "integrate asset picker", "DAM picker", "file picker from Scaleflex"
|
|
22
|
+
- User wants to let users browse/select assets from Scaleflex VXP DAM
|
|
23
|
+
- User asks how to use `@scaleflex/asset-picker` in their project
|
|
24
|
+
|
|
25
|
+
## Step 1 — Detect the Target Framework
|
|
26
|
+
|
|
27
|
+
Read the project's `package.json` to determine:
|
|
28
|
+
- **React** (18+): use the React wrapper (`@scaleflex/asset-picker/react`)
|
|
29
|
+
- **Vue / Angular / Svelte / vanilla JS**: use the Web Component (`@scaleflex/asset-picker/define`)
|
|
30
|
+
|
|
31
|
+
## Step 2 — Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @scaleflex/asset-picker
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`lit` is bundled — no extra peer deps for vanilla JS / Vue / Angular / Svelte.
|
|
38
|
+
For React, `react` and `react-dom` (v18+) must already be installed (they're optional peer deps).
|
|
39
|
+
|
|
40
|
+
### Optional: Uploader integration
|
|
41
|
+
|
|
42
|
+
If the user wants upload functionality inside the picker:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install @scaleflex/uploader
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Step 3 — Add the Picker
|
|
49
|
+
|
|
50
|
+
### Vanilla JS / Web Component
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
import '@scaleflex/asset-picker/define';
|
|
54
|
+
|
|
55
|
+
const picker = document.querySelector('sfx-asset-picker')
|
|
56
|
+
|| document.createElement('sfx-asset-picker');
|
|
57
|
+
document.body.appendChild(picker);
|
|
58
|
+
|
|
59
|
+
picker.config = {
|
|
60
|
+
auth: {
|
|
61
|
+
mode: 'securityTemplate',
|
|
62
|
+
securityTemplateKey: 'YOUR_SECURITY_TEMPLATE_KEY',
|
|
63
|
+
projectToken: 'YOUR_PROJECT_TOKEN',
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
picker.addEventListener('ap-select', (e) => {
|
|
68
|
+
const assets = e.detail.assets;
|
|
69
|
+
console.log('Selected:', assets);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
picker.addEventListener('ap-cancel', () => {
|
|
73
|
+
console.log('Cancelled');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
picker.open();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### React
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { useRef, useState } from 'react';
|
|
83
|
+
import { AssetPicker, type AssetPickerRef } from '@scaleflex/asset-picker/react';
|
|
84
|
+
import type { Asset } from '@scaleflex/asset-picker';
|
|
85
|
+
|
|
86
|
+
function MyComponent() {
|
|
87
|
+
const pickerRef = useRef<AssetPickerRef>(null);
|
|
88
|
+
|
|
89
|
+
const config = {
|
|
90
|
+
auth: {
|
|
91
|
+
mode: 'securityTemplate' as const,
|
|
92
|
+
securityTemplateKey: 'YOUR_SECURITY_TEMPLATE_KEY',
|
|
93
|
+
projectToken: 'YOUR_PROJECT_TOKEN',
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleSelect = (assets: Asset[]) => {
|
|
98
|
+
console.log('Selected:', assets);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<>
|
|
103
|
+
<button onClick={() => pickerRef.current?.open()}>Pick assets</button>
|
|
104
|
+
<AssetPicker
|
|
105
|
+
ref={pickerRef}
|
|
106
|
+
config={config}
|
|
107
|
+
onSelect={handleSelect}
|
|
108
|
+
onCancel={() => console.log('Cancelled')}
|
|
109
|
+
/>
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**React controlled mode** (open state managed by parent):
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
119
|
+
|
|
120
|
+
<AssetPicker
|
|
121
|
+
config={config}
|
|
122
|
+
open={isOpen}
|
|
123
|
+
onSelect={(assets) => { handleSelect(assets); setIsOpen(false); }}
|
|
124
|
+
onCancel={() => setIsOpen(false)}
|
|
125
|
+
/>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Vue
|
|
129
|
+
|
|
130
|
+
```vue
|
|
131
|
+
<template>
|
|
132
|
+
<sfx-asset-picker ref="picker"></sfx-asset-picker>
|
|
133
|
+
<button @click="openPicker">Pick assets</button>
|
|
134
|
+
</template>
|
|
135
|
+
|
|
136
|
+
<script setup>
|
|
137
|
+
import '@scaleflex/asset-picker/define';
|
|
138
|
+
import { ref, onMounted } from 'vue';
|
|
139
|
+
|
|
140
|
+
const picker = ref(null);
|
|
141
|
+
|
|
142
|
+
onMounted(() => {
|
|
143
|
+
const el = picker.value;
|
|
144
|
+
el.config = {
|
|
145
|
+
auth: {
|
|
146
|
+
mode: 'securityTemplate',
|
|
147
|
+
securityTemplateKey: 'YOUR_SECURITY_TEMPLATE_KEY',
|
|
148
|
+
projectToken: 'YOUR_PROJECT_TOKEN',
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
el.addEventListener('ap-select', (e) => {
|
|
153
|
+
console.log('Selected:', e.detail.assets);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
function openPicker() {
|
|
158
|
+
picker.value?.open();
|
|
159
|
+
}
|
|
160
|
+
</script>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Step 4 — Authentication
|
|
164
|
+
|
|
165
|
+
Ask the user which auth mode they need:
|
|
166
|
+
|
|
167
|
+
### Security template (external / public apps)
|
|
168
|
+
|
|
169
|
+
The picker auto-exchanges the key for a SASS key on init. Safer for client-side code.
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
auth: {
|
|
173
|
+
mode: 'securityTemplate',
|
|
174
|
+
securityTemplateKey: string, // From Scaleflex dashboard
|
|
175
|
+
projectToken: string,
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### SASS key (internal / Scaleflex apps)
|
|
180
|
+
|
|
181
|
+
Use when the application already has a SASS key — e.g. inside the Scaleflex Hub where the host app manages SASS key generation and renewal.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
auth: {
|
|
185
|
+
mode: 'sassKey',
|
|
186
|
+
sassKey: string, // X-Filerobot-Key
|
|
187
|
+
projectToken: string,
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Step 5 — Configure (Optional)
|
|
192
|
+
|
|
193
|
+
All options beyond `auth` are optional. Add only what the user needs:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
picker.config = {
|
|
197
|
+
auth: { /* ... */ },
|
|
198
|
+
|
|
199
|
+
// Display
|
|
200
|
+
displayMode: 'modal', // 'modal' (default) or 'inline'
|
|
201
|
+
defaultViewMode: 'grid', // 'grid' (default) or 'list'
|
|
202
|
+
brandColor: '#6366f1', // Hex color for accent theme
|
|
203
|
+
|
|
204
|
+
// Selection
|
|
205
|
+
multiSelect: true, // default: true
|
|
206
|
+
maxSelections: 5, // limit selections
|
|
207
|
+
|
|
208
|
+
// Navigation
|
|
209
|
+
rootFolderPath: '/marketing/', // start in a specific folder
|
|
210
|
+
tabs: ['assets', 'folders'], // default: both. Use ['assets'] to hide folders tab
|
|
211
|
+
rememberLastFolder: true, // persist last folder in localStorage
|
|
212
|
+
rememberLastView: true, // persist grid/list preference
|
|
213
|
+
|
|
214
|
+
// Sorting
|
|
215
|
+
defaultSortBy: 'created_at', // 'name' | 'created_at' | 'modified_at' | 'size' | 'type' | etc.
|
|
216
|
+
defaultSortDirection: 'desc', // 'asc' | 'desc'
|
|
217
|
+
|
|
218
|
+
// Filters
|
|
219
|
+
enabledFilters: ['type', 'tags', 'date'], // restrict visible filters
|
|
220
|
+
defaultFilters: { // pre-applied, user can remove
|
|
221
|
+
type: { type: 'string', values: ['image'] },
|
|
222
|
+
},
|
|
223
|
+
forcedFilters: { // locked, user cannot remove
|
|
224
|
+
tags: { type: 'string', values: ['approved'] },
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
// Metadata
|
|
228
|
+
showMetadata: true, // show metadata in preview panel
|
|
229
|
+
|
|
230
|
+
// Uploader (requires @scaleflex/uploader installed)
|
|
231
|
+
uploader: {
|
|
232
|
+
autoProceed: false,
|
|
233
|
+
restrictions: {
|
|
234
|
+
maxFileSize: 10_000_000, // 10 MB
|
|
235
|
+
allowedFileTypes: ['image/*', 'video/*'],
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Events Reference
|
|
242
|
+
|
|
243
|
+
All events bubble and cross Shadow DOM (`composed: true`):
|
|
244
|
+
|
|
245
|
+
| Event | Detail | When |
|
|
246
|
+
|---|---|---|
|
|
247
|
+
| `ap-select` | `{ assets: Asset[] }` | User confirms selection |
|
|
248
|
+
| `ap-cancel` | `{ reason: 'backdrop' \| 'escape' \| 'button' \| 'close-button' }` | Picker closed without selecting |
|
|
249
|
+
| `ap-open` | `{ timestamp: number }` | Picker opened successfully |
|
|
250
|
+
| `ap-error` | `{ error: Error, context: string }` | Initialization or runtime error |
|
|
251
|
+
|
|
252
|
+
## Public Methods
|
|
253
|
+
|
|
254
|
+
| Method | Returns | Description |
|
|
255
|
+
|---|---|---|
|
|
256
|
+
| `open()` | `Promise<void>` | Open the picker, init API if needed |
|
|
257
|
+
| `close()` | `void` | Close and clear selection |
|
|
258
|
+
|
|
259
|
+
## Asset Object Shape
|
|
260
|
+
|
|
261
|
+
The `Asset` returned in `ap-select`:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
interface Asset {
|
|
265
|
+
uuid: string;
|
|
266
|
+
name: string;
|
|
267
|
+
extension: string;
|
|
268
|
+
type: string; // 'image', 'video', 'audio', 'document', ...
|
|
269
|
+
mime?: string;
|
|
270
|
+
size: { bytes: number; pretty: string };
|
|
271
|
+
url?: {
|
|
272
|
+
public: string; // Public URL
|
|
273
|
+
cdn: string; // CDN-optimised URL
|
|
274
|
+
path: string; // Relative path
|
|
275
|
+
permalink?: string;
|
|
276
|
+
};
|
|
277
|
+
created_at: string;
|
|
278
|
+
modified_at: string;
|
|
279
|
+
tags: Record<string, any>;
|
|
280
|
+
labels: string[];
|
|
281
|
+
meta: { title?: string; description?: string; alt?: string; [key: string]: unknown };
|
|
282
|
+
info: {
|
|
283
|
+
img_w?: number; img_h?: number;
|
|
284
|
+
duration?: number;
|
|
285
|
+
video_w?: number; video_h?: number;
|
|
286
|
+
thumbnail?: string;
|
|
287
|
+
main_colors_hex?: string[];
|
|
288
|
+
dominant_color_hex?: string;
|
|
289
|
+
[key: string]: unknown;
|
|
290
|
+
};
|
|
291
|
+
folder?: { uuid: string; name: string };
|
|
292
|
+
owner?: { uuid: string; name: string; email: string };
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Theming
|
|
297
|
+
|
|
298
|
+
### Quick: brandColor config
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
picker.config = { auth: { /* ... */ }, brandColor: '#6366f1' };
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Advanced: CSS custom properties
|
|
305
|
+
|
|
306
|
+
Override on the element or any ancestor. All use `--ap-` prefix:
|
|
307
|
+
|
|
308
|
+
```css
|
|
309
|
+
sfx-asset-picker {
|
|
310
|
+
--ap-primary: #6366f1;
|
|
311
|
+
--ap-primary-foreground: #fff;
|
|
312
|
+
--ap-background: #ffffff;
|
|
313
|
+
--ap-foreground: #09090b;
|
|
314
|
+
--ap-border: #e4e4e7;
|
|
315
|
+
--ap-muted: #f4f4f5;
|
|
316
|
+
--ap-muted-foreground: #71717a;
|
|
317
|
+
--ap-radius: 8px;
|
|
318
|
+
--ap-font-family: 'Inter', system-ui, sans-serif;
|
|
319
|
+
--ap-modal-max-width: 1400px;
|
|
320
|
+
--ap-modal-max-height: 90vh;
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Filter Data Structures
|
|
325
|
+
|
|
326
|
+
For `defaultFilters` and `forcedFilters`:
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
// String filter (type, mimetype, tags, labels, size, etc.)
|
|
330
|
+
{ type: 'string', values: ['image'], operator?: ':', logic?: 'OR' }
|
|
331
|
+
|
|
332
|
+
// Date filter
|
|
333
|
+
{
|
|
334
|
+
type: 'date',
|
|
335
|
+
field: 'created' | 'updated',
|
|
336
|
+
kind: 'preset' | 'after' | 'before' | 'between' | 'specific' | null,
|
|
337
|
+
preset: 'today' | 'last_week' | 'last_month' | 'last_year' | null,
|
|
338
|
+
from: string | null, // ISO date
|
|
339
|
+
to: string | null, // ISO date
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Filter keys:** `type`, `mimetype`, `date`, `size`, `tags`, `labels`, `color`, `image`, `approval`, `metadata`, `product_ref`, `asset_expiration`, `folders`, `resolution`, `orientation`, `faces`, `products`
|
|
344
|
+
|
|
345
|
+
## Common Patterns
|
|
346
|
+
|
|
347
|
+
### Single image picker
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
config = {
|
|
351
|
+
auth: { /* ... */ },
|
|
352
|
+
multiSelect: false,
|
|
353
|
+
forcedFilters: { type: { type: 'string', values: ['image'] } },
|
|
354
|
+
tabs: ['assets'],
|
|
355
|
+
};
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Inline mode (embedded in page, not modal)
|
|
359
|
+
|
|
360
|
+
```ts
|
|
361
|
+
config = {
|
|
362
|
+
auth: { /* ... */ },
|
|
363
|
+
displayMode: 'inline',
|
|
364
|
+
};
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Style the container height:
|
|
368
|
+
```css
|
|
369
|
+
sfx-asset-picker { --ap-inline-height: 500px; }
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### With uploader drop zone
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
config = {
|
|
376
|
+
auth: { /* ... */ },
|
|
377
|
+
uploader: {
|
|
378
|
+
autoProceed: true,
|
|
379
|
+
restrictions: { maxFileSize: 50_000_000 },
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Requires `@scaleflex/uploader` installed as peer dependency.
|
|
385
|
+
|
|
386
|
+
## Troubleshooting
|
|
387
|
+
|
|
388
|
+
- **"customElements is not defined"** — SSR environment. The React wrapper handles this automatically. For vanilla JS, guard the import: `if (typeof customElements !== 'undefined') import('@scaleflex/asset-picker/define');`
|
|
389
|
+
- **Styles not showing** — The component uses Shadow DOM; external CSS won't penetrate. Use `--ap-*` CSS custom properties for theming.
|
|
390
|
+
- **Auth errors** — Check that the security template key or SASS key is valid and the project token matches.
|
|
391
|
+
- **`open()` does nothing** — `config` must be set before calling `open()`. Ensure `auth` is provided.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<a href="https://www.scaleflex.com">
|
|
3
|
-
<img src="https://scaleflex.cloudimg.io/v7/plugins/
|
|
3
|
+
<img src="https://scaleflex.cloudimg.io/v7/plugins/scaleflex/logo.png?vh=b0a502&radius=25&w=700" alt="Scaleflex" width="350">
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
- [Asset](#asset)
|
|
55
55
|
- [Folder](#folder)
|
|
56
56
|
- [Browser Support](#browser-support)
|
|
57
|
+
- [Claude Code Integration](#claude-code-integration)
|
|
57
58
|
- [License](#license)
|
|
58
59
|
|
|
59
60
|
---
|
|
@@ -68,7 +69,7 @@ The npm package contains **only pre-built, minified production files** (`dist/`)
|
|
|
68
69
|
|
|
69
70
|
- **Framework-agnostic** — standard `<sfx-asset-picker>` custom element, works in any stack
|
|
70
71
|
- **First-class React wrapper** — `forwardRef` component with controlled `open` prop and imperative ref
|
|
71
|
-
- **Two auth modes** —
|
|
72
|
+
- **Two auth modes** — security templates or direct SASS key
|
|
72
73
|
- **Grid & list views** — switchable with persistent user preference
|
|
73
74
|
- **Full-text search** — real-time search across your DAM
|
|
74
75
|
- **14+ filter types** — type, date, size, tags, labels, color, approval status, metadata, and more
|
|
@@ -88,7 +89,7 @@ The npm package contains **only pre-built, minified production files** (`dist/`)
|
|
|
88
89
|
## Requirements
|
|
89
90
|
|
|
90
91
|
- A [Scaleflex](https://www.scaleflex.com) VXP DAM account with a project token
|
|
91
|
-
- Either **
|
|
92
|
+
- Either a **security template key** or a **SASS key** for authentication
|
|
92
93
|
- Modern browser with Custom Elements v1 support (see [Browser Support](#browser-support))
|
|
93
94
|
|
|
94
95
|
## Installation
|
|
@@ -198,7 +199,7 @@ The picker supports two authentication modes:
|
|
|
198
199
|
|
|
199
200
|
#### Security template (external / public apps)
|
|
200
201
|
|
|
201
|
-
Use for client-side integrations
|
|
202
|
+
Use for client-side integrations. The picker automatically exchanges the security template key for a SASS key on init.
|
|
202
203
|
|
|
203
204
|
```ts
|
|
204
205
|
{
|
|
@@ -210,17 +211,16 @@ Use for client-side integrations where you don't want to expose session tokens.
|
|
|
210
211
|
}
|
|
211
212
|
```
|
|
212
213
|
|
|
213
|
-
####
|
|
214
|
+
#### SASS key (internal / Scaleflex apps)
|
|
214
215
|
|
|
215
|
-
Use when your
|
|
216
|
+
Use when your application already has a SASS key — e.g. inside the Scaleflex Hub where the host app manages SASS key generation and renewal.
|
|
216
217
|
|
|
217
218
|
```ts
|
|
218
219
|
{
|
|
219
220
|
auth: {
|
|
220
|
-
mode: '
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
projectToken: string, // X-Project-Token
|
|
221
|
+
mode: 'sassKey',
|
|
222
|
+
sassKey: string, // X-Filerobot-Key
|
|
223
|
+
projectToken: string,
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
```
|
|
@@ -583,8 +583,8 @@ All types are exported from the main entry point:
|
|
|
583
583
|
import type {
|
|
584
584
|
AssetPickerConfig,
|
|
585
585
|
AuthConfig,
|
|
586
|
-
SessionAuth,
|
|
587
586
|
SecurityTemplateAuth,
|
|
587
|
+
SassKeyAuth,
|
|
588
588
|
Asset,
|
|
589
589
|
Folder,
|
|
590
590
|
FilterKey,
|
|
@@ -691,6 +691,38 @@ Requires native support for Custom Elements v1, Shadow DOM, and ES2020+. Interne
|
|
|
691
691
|
|
|
692
692
|
---
|
|
693
693
|
|
|
694
|
+
## Claude Code Integration
|
|
695
|
+
|
|
696
|
+
If you use [Claude Code](https://docs.anthropic.com/en/docs/claude-code), this package ships with a ready-made skill that helps Claude add the asset picker to your project — detecting your framework, wiring auth, events, theming, and filters automatically.
|
|
697
|
+
|
|
698
|
+
### Option 1: Project-level (recommended)
|
|
699
|
+
|
|
700
|
+
Copy the skill into your project so every team member who uses Claude Code gets it:
|
|
701
|
+
|
|
702
|
+
```bash
|
|
703
|
+
mkdir -p .claude/skills/integrate-asset-picker
|
|
704
|
+
cp node_modules/@scaleflex/asset-picker/.claude/skills/integrate-asset-picker/SKILL.md \
|
|
705
|
+
.claude/skills/integrate-asset-picker/SKILL.md
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
Commit the `.claude/skills/` directory to version control. The skill is now available to everyone on the team.
|
|
709
|
+
|
|
710
|
+
### Option 2: Global (personal)
|
|
711
|
+
|
|
712
|
+
Install it once for all your projects:
|
|
713
|
+
|
|
714
|
+
```bash
|
|
715
|
+
mkdir -p ~/.claude/skills/integrate-asset-picker
|
|
716
|
+
cp node_modules/@scaleflex/asset-picker/.claude/skills/integrate-asset-picker/SKILL.md \
|
|
717
|
+
~/.claude/skills/integrate-asset-picker/SKILL.md
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### Usage
|
|
721
|
+
|
|
722
|
+
Type `/integrate-asset-picker` in Claude Code and it will walk you through the full integration — install, config, events, and theming — tailored to your stack (React, Vue, vanilla JS, etc.).
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
694
726
|
## License
|
|
695
727
|
|
|
696
728
|
**PROPRIETARY** — All Rights Reserved.
|
|
@@ -259,7 +259,7 @@ class Is {
|
|
|
259
259
|
constructor(e, s) {
|
|
260
260
|
this.auth = e;
|
|
261
261
|
const i = e.projectToken;
|
|
262
|
-
this.baseUrl = s || `https://api.filerobot.com/${i}/v5
|
|
262
|
+
this.baseUrl = s || `https://api.filerobot.com/${i}/v5`, e.mode === "sassKey" && (this.sassKey = e.sassKey);
|
|
263
263
|
}
|
|
264
264
|
setSassKey(e) {
|
|
265
265
|
this.sassKey = e;
|
|
@@ -268,19 +268,16 @@ class Is {
|
|
|
268
268
|
if (this.auth.mode === "securityTemplate")
|
|
269
269
|
return this.auth.securityTemplateKey;
|
|
270
270
|
}
|
|
271
|
+
_applyAuthHeaders(e) {
|
|
272
|
+
this.sassKey ? e["X-Filerobot-Key"] = this.sassKey : this.auth.mode === "securityTemplate" && (e["X-Filerobot-Key"] = this.auth.securityTemplateKey);
|
|
273
|
+
}
|
|
271
274
|
async request(e, s) {
|
|
272
275
|
const i = new URL(`${this.baseUrl}${e}`);
|
|
273
276
|
s && Object.entries(s).forEach(([l, c]) => {
|
|
274
277
|
c != null && (Array.isArray(c) ? i.searchParams.set(l, c.join(",")) : i.searchParams.set(l, String(c)));
|
|
275
278
|
});
|
|
276
279
|
const a = {};
|
|
277
|
-
|
|
278
|
-
const l = this.auth;
|
|
279
|
-
a["X-Session-Token"] = l.sessionToken, a["X-Company-Token"] = l.companyToken, a["X-Project-Token"] = l.projectToken;
|
|
280
|
-
} else {
|
|
281
|
-
const l = this.auth;
|
|
282
|
-
this.sassKey ? a["X-Filerobot-Key"] = this.sassKey : a["X-Filerobot-Key"] = l.securityTemplateKey;
|
|
283
|
-
}
|
|
280
|
+
this._applyAuthHeaders(a);
|
|
284
281
|
const r = new AbortController(), o = setTimeout(() => r.abort(), 3e4);
|
|
285
282
|
try {
|
|
286
283
|
const l = await fetch(i.toString(), { headers: a, signal: r.signal });
|
|
@@ -305,13 +302,7 @@ class Is {
|
|
|
305
302
|
const i = new URL(`${this.baseUrl}${e}`), a = {
|
|
306
303
|
"Content-Type": "application/json"
|
|
307
304
|
};
|
|
308
|
-
|
|
309
|
-
const l = this.auth;
|
|
310
|
-
a["X-Session-Token"] = l.sessionToken, a["X-Company-Token"] = l.companyToken, a["X-Project-Token"] = l.projectToken;
|
|
311
|
-
} else {
|
|
312
|
-
const l = this.auth;
|
|
313
|
-
this.sassKey ? a["X-Filerobot-Key"] = this.sassKey : a["X-Filerobot-Key"] = l.securityTemplateKey;
|
|
314
|
-
}
|
|
305
|
+
this._applyAuthHeaders(a);
|
|
315
306
|
const r = new AbortController(), o = setTimeout(() => r.abort(), 3e4);
|
|
316
307
|
try {
|
|
317
308
|
const l = await fetch(i.toString(), {
|
|
@@ -10734,10 +10725,9 @@ const Ht = class Ht extends w {
|
|
|
10734
10725
|
container: e.auth.projectToken,
|
|
10735
10726
|
securityTemplateId: e.auth.securityTemplateKey
|
|
10736
10727
|
} : a = {
|
|
10737
|
-
mode: "
|
|
10728
|
+
mode: "sass-key",
|
|
10738
10729
|
container: e.auth.projectToken,
|
|
10739
|
-
|
|
10740
|
-
companyToken: e.auth.companyToken
|
|
10730
|
+
sassKey: e.auth.sassKey
|
|
10741
10731
|
}, {
|
|
10742
10732
|
auth: a,
|
|
10743
10733
|
targetFolder: i.currentFolderPath || "/",
|