@scaleflex/asset-picker 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.
- package/CHANGELOG.md +53 -0
- package/LICENSE +50 -0
- package/README.md +702 -0
- package/dist/asset-picker-BA876lMW.js +11444 -0
- package/dist/asset-picker-BbEOZw7O.cjs +5865 -0
- package/dist/asset-picker.d.ts +77 -0
- package/dist/asset-picker.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-approval.d.ts +43 -0
- package/dist/components/filters/ap-filter-approval.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-color.d.ts +31 -0
- package/dist/components/filters/ap-filter-color.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-date.d.ts +32 -0
- package/dist/components/filters/ap-filter-date.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-image.d.ts +21 -0
- package/dist/components/filters/ap-filter-image.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-labels.d.ts +26 -0
- package/dist/components/filters/ap-filter-labels.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-metadata.d.ts +93 -0
- package/dist/components/filters/ap-filter-metadata.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-popover.d.ts +13 -0
- package/dist/components/filters/ap-filter-popover.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-product-ref.d.ts +38 -0
- package/dist/components/filters/ap-filter-product-ref.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-size.d.ts +24 -0
- package/dist/components/filters/ap-filter-size.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-tags.d.ts +31 -0
- package/dist/components/filters/ap-filter-tags.d.ts.map +1 -0
- package/dist/components/filters/ap-filter-type.d.ts +13 -0
- package/dist/components/filters/ap-filter-type.d.ts.map +1 -0
- package/dist/components/filters/ap-filters-bar.d.ts +40 -0
- package/dist/components/filters/ap-filters-bar.d.ts.map +1 -0
- package/dist/components/filters/filters.constants.d.ts +189 -0
- package/dist/components/filters/filters.constants.d.ts.map +1 -0
- package/dist/components/filters/shared/filter-styles.d.ts +10 -0
- package/dist/components/filters/shared/filter-styles.d.ts.map +1 -0
- package/dist/components/header/ap-header.d.ts +30 -0
- package/dist/components/header/ap-header.d.ts.map +1 -0
- package/dist/components/header/ap-regional-settings.d.ts +19 -0
- package/dist/components/header/ap-regional-settings.d.ts.map +1 -0
- package/dist/components/modal/ap-modal.d.ts +17 -0
- package/dist/components/modal/ap-modal.d.ts.map +1 -0
- package/dist/components/navigation/ap-breadcrumb.d.ts +14 -0
- package/dist/components/navigation/ap-breadcrumb.d.ts.map +1 -0
- package/dist/components/preview/ap-preview-panel.d.ts +80 -0
- package/dist/components/preview/ap-preview-panel.d.ts.map +1 -0
- package/dist/components/selection/ap-marquee-overlay.d.ts +14 -0
- package/dist/components/selection/ap-marquee-overlay.d.ts.map +1 -0
- package/dist/components/selection/ap-selection-bar.d.ts +21 -0
- package/dist/components/selection/ap-selection-bar.d.ts.map +1 -0
- package/dist/components/shared/ap-badge.d.ts +12 -0
- package/dist/components/shared/ap-badge.d.ts.map +1 -0
- package/dist/components/shared/ap-checkbox.d.ts +17 -0
- package/dist/components/shared/ap-checkbox.d.ts.map +1 -0
- package/dist/components/shared/ap-dropdown.d.ts +37 -0
- package/dist/components/shared/ap-dropdown.d.ts.map +1 -0
- package/dist/components/shared/ap-icon.d.ts +13 -0
- package/dist/components/shared/ap-icon.d.ts.map +1 -0
- package/dist/components/shared/ap-popover.d.ts +15 -0
- package/dist/components/shared/ap-popover.d.ts.map +1 -0
- package/dist/components/shared/ap-radio-group.d.ts +30 -0
- package/dist/components/shared/ap-radio-group.d.ts.map +1 -0
- package/dist/components/shared/ap-spinner.d.ts +12 -0
- package/dist/components/shared/ap-spinner.d.ts.map +1 -0
- package/dist/components/shared/ap-tooltip.d.ts +12 -0
- package/dist/components/shared/ap-tooltip.d.ts.map +1 -0
- package/dist/components/toolbar/ap-content-toolbar.d.ts +64 -0
- package/dist/components/toolbar/ap-content-toolbar.d.ts.map +1 -0
- package/dist/components/toolbar/sort.constants.d.ts +9 -0
- package/dist/components/toolbar/sort.constants.d.ts.map +1 -0
- package/dist/components/views/ap-asset-card.d.ts +20 -0
- package/dist/components/views/ap-asset-card.d.ts.map +1 -0
- package/dist/components/views/ap-asset-row.d.ts +18 -0
- package/dist/components/views/ap-asset-row.d.ts.map +1 -0
- package/dist/components/views/ap-folder-card.d.ts +27 -0
- package/dist/components/views/ap-folder-card.d.ts.map +1 -0
- package/dist/components/views/ap-folder-row.d.ts +14 -0
- package/dist/components/views/ap-folder-row.d.ts.map +1 -0
- package/dist/components/views/ap-grid-view.d.ts +25 -0
- package/dist/components/views/ap-grid-view.d.ts.map +1 -0
- package/dist/components/views/ap-list-view.d.ts +22 -0
- package/dist/components/views/ap-list-view.d.ts.map +1 -0
- package/dist/components/views/ap-skeleton.d.ts +12 -0
- package/dist/components/views/ap-skeleton.d.ts.map +1 -0
- package/dist/controllers/infinite-scroll.controller.d.ts +13 -0
- package/dist/controllers/infinite-scroll.controller.d.ts.map +1 -0
- package/dist/controllers/keyboard.controller.d.ts +10 -0
- package/dist/controllers/keyboard.controller.d.ts.map +1 -0
- package/dist/controllers/marquee.controller.d.ts +43 -0
- package/dist/controllers/marquee.controller.d.ts.map +1 -0
- package/dist/controllers/selection.controller.d.ts +19 -0
- package/dist/controllers/selection.controller.d.ts.map +1 -0
- package/dist/controllers/store.controller.d.ts +14 -0
- package/dist/controllers/store.controller.d.ts.map +1 -0
- package/dist/define.cjs +1 -0
- package/dist/define.d.ts +2 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +2 -0
- package/dist/hls.light-C3NKRmfw.cjs +27 -0
- package/dist/hls.light-DxDlt6yF.js +14441 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/react.cjs +1 -0
- package/dist/react.d.ts +17 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +46 -0
- package/dist/services/api-client.d.ts +12 -0
- package/dist/services/api-client.d.ts.map +1 -0
- package/dist/services/auth.service.d.ts +3 -0
- package/dist/services/auth.service.d.ts.map +1 -0
- package/dist/services/files.service.d.ts +21 -0
- package/dist/services/files.service.d.ts.map +1 -0
- package/dist/services/filters.service.d.ts +13 -0
- package/dist/services/filters.service.d.ts.map +1 -0
- package/dist/services/folders.service.d.ts +26 -0
- package/dist/services/folders.service.d.ts.map +1 -0
- package/dist/services/labels.service.d.ts +4 -0
- package/dist/services/labels.service.d.ts.map +1 -0
- package/dist/services/settings.service.d.ts +4 -0
- package/dist/services/settings.service.d.ts.map +1 -0
- package/dist/services/tags.service.d.ts +4 -0
- package/dist/services/tags.service.d.ts.map +1 -0
- package/dist/store/index.d.ts +6 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/store.d.ts +14 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.types.d.ts +49 -0
- package/dist/store/store.types.d.ts.map +1 -0
- package/dist/styles/shared-styles.d.ts +4 -0
- package/dist/styles/shared-styles.d.ts.map +1 -0
- package/dist/types/api.types.d.ts +82 -0
- package/dist/types/api.types.d.ts.map +1 -0
- package/dist/types/asset.types.d.ts +77 -0
- package/dist/types/asset.types.d.ts.map +1 -0
- package/dist/types/config.types.d.ts +51 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/events.types.d.ts +23 -0
- package/dist/types/events.types.d.ts.map +1 -0
- package/dist/types/filter.types.d.ts +190 -0
- package/dist/types/filter.types.d.ts.map +1 -0
- package/dist/types/folder.types.d.ts +27 -0
- package/dist/types/folder.types.d.ts.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/label.types.d.ts +9 -0
- package/dist/types/label.types.d.ts.map +1 -0
- package/dist/types/tag.types.d.ts +13 -0
- package/dist/types/tag.types.d.ts.map +1 -0
- package/dist/utils/brand-color.d.ts +12 -0
- package/dist/utils/brand-color.d.ts.map +1 -0
- package/dist/utils/css-helpers.d.ts +2 -0
- package/dist/utils/css-helpers.d.ts.map +1 -0
- package/dist/utils/debounce.d.ts +4 -0
- package/dist/utils/debounce.d.ts.map +1 -0
- package/dist/utils/file-type.d.ts +25 -0
- package/dist/utils/file-type.d.ts.map +1 -0
- package/dist/utils/filter-date.d.ts +9 -0
- package/dist/utils/filter-date.d.ts.map +1 -0
- package/dist/utils/filter-normalize.d.ts +7 -0
- package/dist/utils/filter-normalize.d.ts.map +1 -0
- package/dist/utils/filter-pin-storage.d.ts +8 -0
- package/dist/utils/filter-pin-storage.d.ts.map +1 -0
- package/dist/utils/filter-serialize.d.ts +3 -0
- package/dist/utils/filter-serialize.d.ts.map +1 -0
- package/dist/utils/filter-url.d.ts +8 -0
- package/dist/utils/filter-url.d.ts.map +1 -0
- package/dist/utils/filter-validate.d.ts +3 -0
- package/dist/utils/filter-validate.d.ts.map +1 -0
- package/dist/utils/format.d.ts +5 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/preference-storage.d.ts +6 -0
- package/dist/utils/preference-storage.d.ts.map +1 -0
- package/dist/utils/sort-storage.d.ts +7 -0
- package/dist/utils/sort-storage.d.ts.map +1 -0
- package/dist/utils/thumbnail.d.ts +27 -0
- package/dist/utils/thumbnail.d.ts.map +1 -0
- package/dist/utils/video.d.ts +7 -0
- package/dist/utils/video.d.ts.map +1 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://www.scaleflex.com">
|
|
3
|
+
<img src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/logo_scaleflex_on_white_bg.jpg?vh=91b12d&w=700" alt="Scaleflex" width="350">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">@scaleflex/asset-picker</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Framework-agnostic Asset Picker Web Component for <a href="https://www.scaleflex.com/page/digital-asset-management">Scaleflex VXP DAM</a>.<br>
|
|
11
|
+
Browse, search, filter, and select assets from your DAM — in any frontend stack.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://www.npmjs.com/package/@scaleflex/asset-picker"><img src="https://img.shields.io/npm/v/@scaleflex/asset-picker.svg?style=flat-square" alt="npm version"></a>
|
|
16
|
+
<a href="https://www.npmjs.com/package/@scaleflex/asset-picker"><img src="https://img.shields.io/npm/dm/@scaleflex/asset-picker.svg?style=flat-square" alt="npm downloads"></a>
|
|
17
|
+
<img src="https://img.shields.io/badge/license-proprietary-red?style=flat-square" alt="license">
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Table of Contents
|
|
23
|
+
|
|
24
|
+
- [Overview](#overview)
|
|
25
|
+
- [Features](#features)
|
|
26
|
+
- [Requirements](#requirements)
|
|
27
|
+
- [Installation](#installation)
|
|
28
|
+
- [Quick Start](#quick-start)
|
|
29
|
+
- [Vanilla JS / Web Component](#vanilla-js--web-component)
|
|
30
|
+
- [React](#react)
|
|
31
|
+
- [Configuration](#configuration)
|
|
32
|
+
- [Authentication](#authentication)
|
|
33
|
+
- [Config Options](#config-options)
|
|
34
|
+
- [Default & Forced Filters](#default--forced-filters)
|
|
35
|
+
- [Public Methods](#public-methods)
|
|
36
|
+
- [Events](#events)
|
|
37
|
+
- [React API](#react-api)
|
|
38
|
+
- [Theming](#theming)
|
|
39
|
+
- [Brand Color](#brand-color)
|
|
40
|
+
- [CSS Custom Properties](#css-custom-properties)
|
|
41
|
+
- [Filters Reference](#filters-reference)
|
|
42
|
+
- [Filter Keys](#filter-keys)
|
|
43
|
+
- [Filter Data Structures](#filter-data-structures)
|
|
44
|
+
- [Types Reference](#types-reference)
|
|
45
|
+
- [Asset](#asset)
|
|
46
|
+
- [Folder](#folder)
|
|
47
|
+
- [Browser Support](#browser-support)
|
|
48
|
+
- [License](#license)
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Overview
|
|
53
|
+
|
|
54
|
+
`@scaleflex/asset-picker` is a drop-in modal component that connects to a [Scaleflex VXP](https://www.scaleflex.com) DAM project and lets users browse, search, filter, preview, and select digital assets. It ships as a standard [Web Component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) (Custom Element) built with [Lit 3](https://lit.dev/), so it works everywhere — vanilla JS, React, Vue, Angular, Svelte, or any other framework.
|
|
55
|
+
|
|
56
|
+
The npm package contains **only pre-built, minified production files** (`dist/`). Source code is maintained in a private Scaleflex GitLab repository.
|
|
57
|
+
|
|
58
|
+
## Features
|
|
59
|
+
|
|
60
|
+
- **Framework-agnostic** — standard `<asset-picker>` custom element, works in any stack
|
|
61
|
+
- **First-class React wrapper** — `forwardRef` component with controlled `open` prop and imperative ref
|
|
62
|
+
- **Two auth modes** — session tokens or security templates
|
|
63
|
+
- **Grid & list views** — switchable with persistent user preference
|
|
64
|
+
- **Full-text search** — real-time search across your DAM
|
|
65
|
+
- **14+ filter types** — type, date, size, tags, labels, color, approval status, metadata, and more
|
|
66
|
+
- **Filter pinning** — users can pin favourite filters; persisted to `localStorage`
|
|
67
|
+
- **Default & forced filters** — pre-apply filters on open or lock filters the user cannot remove
|
|
68
|
+
- **Infinite scroll** — automatic pagination as the user scrolls
|
|
69
|
+
- **Folder navigation** — browse the full DAM folder tree with breadcrumb
|
|
70
|
+
- **Asset preview panel** — side panel with metadata, thumbnails, and video/audio playback
|
|
71
|
+
- **Multi-select & select all** — single or bulk selection with configurable max
|
|
72
|
+
- **Keyboard navigation** — arrow keys, Enter, Escape, Shift+click range select
|
|
73
|
+
- **Marquee selection** — click-and-drag to select multiple assets
|
|
74
|
+
- **Approval workflow** — filter by approval status, approver, requester, due date
|
|
75
|
+
- **Regional variants** — metadata variant groups with per-variant filtering
|
|
76
|
+
- **Customisable theming** — brand color config + 20 CSS custom properties
|
|
77
|
+
- **Tiny footprint** — ~70 KB gzipped (main chunk)
|
|
78
|
+
|
|
79
|
+
## Requirements
|
|
80
|
+
|
|
81
|
+
- A [Scaleflex](https://www.scaleflex.com) VXP DAM account with a project token
|
|
82
|
+
- Either **session credentials** or a **security template key** for authentication
|
|
83
|
+
- Modern browser with Custom Elements v1 support (see [Browser Support](#browser-support))
|
|
84
|
+
|
|
85
|
+
## Installation
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install @scaleflex/asset-picker
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
yarn add @scaleflex/asset-picker
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pnpm add @scaleflex/asset-picker
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`lit` is bundled with the package. For React usage, you also need `react` and `react-dom` (v18+) as peer dependencies.
|
|
100
|
+
|
|
101
|
+
### Package exports
|
|
102
|
+
|
|
103
|
+
| Export path | Description |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `@scaleflex/asset-picker` | `AssetPicker` class + all TypeScript types |
|
|
106
|
+
| `@scaleflex/asset-picker/react` | React wrapper component |
|
|
107
|
+
| `@scaleflex/asset-picker/define` | Side-effect import — registers `<asset-picker>` custom element |
|
|
108
|
+
|
|
109
|
+
Both ESM (`import`) and CJS (`require`) builds are provided.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Quick Start
|
|
114
|
+
|
|
115
|
+
### Vanilla JS / Web Component
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<asset-picker></asset-picker>
|
|
119
|
+
|
|
120
|
+
<script type="module">
|
|
121
|
+
// 1. Register the custom element (once)
|
|
122
|
+
import '@scaleflex/asset-picker/define';
|
|
123
|
+
|
|
124
|
+
// 2. Grab the element
|
|
125
|
+
const picker = document.querySelector('asset-picker');
|
|
126
|
+
|
|
127
|
+
// 3. Configure
|
|
128
|
+
picker.config = {
|
|
129
|
+
auth: {
|
|
130
|
+
mode: 'securityTemplate',
|
|
131
|
+
securityTemplateKey: 'YOUR_KEY',
|
|
132
|
+
projectToken: 'YOUR_TOKEN',
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// 4. Listen for events
|
|
137
|
+
picker.addEventListener('ap-select', (e) => {
|
|
138
|
+
console.log('Selected assets:', e.detail.assets);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
picker.addEventListener('ap-cancel', (e) => {
|
|
142
|
+
console.log('Cancelled via:', e.detail.reason);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// 5. Open
|
|
146
|
+
picker.open();
|
|
147
|
+
</script>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### React
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { useRef } from 'react';
|
|
154
|
+
import { AssetPicker, type AssetPickerRef } from '@scaleflex/asset-picker/react';
|
|
155
|
+
|
|
156
|
+
function App() {
|
|
157
|
+
const pickerRef = useRef<AssetPickerRef>(null);
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<>
|
|
161
|
+
<button onClick={() => pickerRef.current?.open()}>
|
|
162
|
+
Pick assets
|
|
163
|
+
</button>
|
|
164
|
+
|
|
165
|
+
<AssetPicker
|
|
166
|
+
ref={pickerRef}
|
|
167
|
+
config={{
|
|
168
|
+
auth: {
|
|
169
|
+
mode: 'securityTemplate',
|
|
170
|
+
securityTemplateKey: 'YOUR_KEY',
|
|
171
|
+
projectToken: 'YOUR_TOKEN',
|
|
172
|
+
},
|
|
173
|
+
}}
|
|
174
|
+
onSelect={(assets) => console.log(assets)}
|
|
175
|
+
onCancel={() => console.log('Cancelled')}
|
|
176
|
+
/>
|
|
177
|
+
</>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Configuration
|
|
185
|
+
|
|
186
|
+
### Authentication
|
|
187
|
+
|
|
188
|
+
The picker supports two authentication modes:
|
|
189
|
+
|
|
190
|
+
#### Security template (external / public apps)
|
|
191
|
+
|
|
192
|
+
Use for client-side integrations where you don't want to expose session tokens. The picker automatically exchanges the key for a SASS key on init.
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
{
|
|
196
|
+
auth: {
|
|
197
|
+
mode: 'securityTemplate',
|
|
198
|
+
securityTemplateKey: string, // Exchanged for a SASS key via API
|
|
199
|
+
projectToken: string,
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### Session (internal / Scaleflex apps)
|
|
205
|
+
|
|
206
|
+
Use when your backend already manages Scaleflex sessions.
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
{
|
|
210
|
+
auth: {
|
|
211
|
+
mode: 'session',
|
|
212
|
+
sessionToken: string, // X-Session-Token
|
|
213
|
+
companyToken: string, // X-Company-Token
|
|
214
|
+
projectToken: string, // X-Project-Token
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Config Options
|
|
220
|
+
|
|
221
|
+
| Property | Type | Default | Description |
|
|
222
|
+
|---|---|---|---|
|
|
223
|
+
| `auth` | `AuthConfig` | **required** | Authentication credentials (see above) |
|
|
224
|
+
| `apiBase` | `string` | auto | Override the API base URL |
|
|
225
|
+
| `locale` | `string` | `undefined` | Locale for translations |
|
|
226
|
+
| `multiSelect` | `boolean` | `true` | Enable multi-asset selection |
|
|
227
|
+
| `maxSelections` | `number` | `undefined` | Maximum number of selectable assets |
|
|
228
|
+
| `defaultViewMode` | `'grid' \| 'list'` | `'grid'` | Initial view mode |
|
|
229
|
+
| `defaultSortBy` | `SortBy` | `'created_at'` | Initial sort field (see table below) |
|
|
230
|
+
| `defaultSortDirection` | `'asc' \| 'desc'` | `'desc'` | Initial sort direction |
|
|
231
|
+
| `hiddenTabs` | `TabKey[]` | `[]` | Tabs to hide: `'assets'`, `'folders'` |
|
|
232
|
+
| `enabledFilters` | `FilterKey[]` | all | Restrict which filters appear in the toolbar |
|
|
233
|
+
| `allowedFileTypes` | `string[]` | `undefined` | Restrict selectable file types (e.g. `['image', 'video']`) |
|
|
234
|
+
| `rootFolderUuid` | `string` | `undefined` | Start browsing from a specific folder UUID |
|
|
235
|
+
| `showMetadata` | `boolean` | `true` | Show metadata sections in the preview panel |
|
|
236
|
+
| `brandColor` | `string` | from API | Brand accent colour as hex (e.g. `'#3b82f6'`). Overrides the API-fetched value |
|
|
237
|
+
| `defaultFilters` | `Filters` | `undefined` | Filters pre-applied on open. User can modify/remove |
|
|
238
|
+
| `forcedFilters` | `Filters` | `undefined` | Filters always active. Shown as locked chips the user cannot remove |
|
|
239
|
+
| `onSelect` | `(assets: Asset[]) => void` | `undefined` | Callback when assets are selected |
|
|
240
|
+
| `onCancel` | `() => void` | `undefined` | Callback when the picker is cancelled |
|
|
241
|
+
|
|
242
|
+
#### Sort fields
|
|
243
|
+
|
|
244
|
+
| Value | Available in |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `'name'` | Assets, Folders |
|
|
247
|
+
| `'created_at'` | Assets, Folders |
|
|
248
|
+
| `'modified_at'` | Assets, Folders |
|
|
249
|
+
| `'size'` | Assets |
|
|
250
|
+
| `'type'` | Assets |
|
|
251
|
+
| `'relevance'` | Search results only |
|
|
252
|
+
| `'title'` | Assets |
|
|
253
|
+
| `'color'` | Assets |
|
|
254
|
+
| `'uploaded'` | Assets |
|
|
255
|
+
| `'updated_at'` | Assets |
|
|
256
|
+
| `'files_count_recursive'` | Folders only |
|
|
257
|
+
| `'files_size_recursive'` | Folders only |
|
|
258
|
+
|
|
259
|
+
### Default & Forced Filters
|
|
260
|
+
|
|
261
|
+
You can pre-configure filters that are applied when the picker opens, and/or lock filters that the user cannot remove.
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
picker.config = {
|
|
265
|
+
auth: { /* ... */ },
|
|
266
|
+
|
|
267
|
+
// Pre-applied on open — user can modify or remove
|
|
268
|
+
defaultFilters: {
|
|
269
|
+
type: { type: 'string', values: ['image'] },
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
// Always active — locked chip with lock icon, cannot be removed
|
|
273
|
+
forcedFilters: {
|
|
274
|
+
tags: { type: 'string', values: ['approved'] },
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Behaviour:**
|
|
280
|
+
|
|
281
|
+
- **`defaultFilters`** are seeded into the applied filters state when `open()` is called. The user sees them as normal filter chips and can modify or remove them freely.
|
|
282
|
+
- **`forcedFilters`** are merged into every API request but are **not** stored in the mutable applied state. They render as locked chips (with a lock icon instead of an X button). The user cannot remove them, and "Clear filters" does not affect them. Forced filter keys are also hidden from the "Add filter" dropdown.
|
|
283
|
+
- If the same key appears in both `defaultFilters` and `forcedFilters`, the forced filter takes precedence — the default filter for that key is skipped.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Public Methods
|
|
288
|
+
|
|
289
|
+
| Method | Returns | Description |
|
|
290
|
+
|---|---|---|
|
|
291
|
+
| `open()` | `Promise<void>` | Opens the picker modal. Initialises the API client and loads initial data if not already done. Fires `ap-open` on success. |
|
|
292
|
+
| `close()` | `void` | Closes the picker modal and clears the selection state. |
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
// Open the picker
|
|
296
|
+
await picker.open();
|
|
297
|
+
|
|
298
|
+
// Close programmatically
|
|
299
|
+
picker.close();
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Events
|
|
305
|
+
|
|
306
|
+
All events bubble and cross shadow DOM boundaries (`composed: true`).
|
|
307
|
+
|
|
308
|
+
| Event | Detail | Description |
|
|
309
|
+
|---|---|---|
|
|
310
|
+
| `ap-select` | `{ assets: Asset[] }` | Fired when the user confirms their selection |
|
|
311
|
+
| `ap-cancel` | `{ reason: 'backdrop' \| 'escape' \| 'button' \| 'close-button' }` | Fired when the picker is closed without selecting |
|
|
312
|
+
| `ap-open` | `{ timestamp: number }` | Fired when the picker opens successfully |
|
|
313
|
+
| `ap-error` | `{ error: Error, context: string }` | Fired on initialisation or runtime errors |
|
|
314
|
+
|
|
315
|
+
```js
|
|
316
|
+
picker.addEventListener('ap-select', (e) => {
|
|
317
|
+
const { assets } = e.detail;
|
|
318
|
+
assets.forEach((asset) => {
|
|
319
|
+
console.log(asset.name, asset.url?.cdn);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
picker.addEventListener('ap-cancel', (e) => {
|
|
324
|
+
console.log('Cancelled via:', e.detail.reason);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
picker.addEventListener('ap-error', (e) => {
|
|
328
|
+
console.error(`[${e.detail.context}]`, e.detail.error);
|
|
329
|
+
});
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## React API
|
|
335
|
+
|
|
336
|
+
```tsx
|
|
337
|
+
import { AssetPicker, type AssetPickerRef, type AssetPickerProps } from '@scaleflex/asset-picker/react';
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Props
|
|
341
|
+
|
|
342
|
+
| Prop | Type | Description |
|
|
343
|
+
|---|---|---|
|
|
344
|
+
| `config` | `AssetPickerConfig` | Configuration object (see [Config Options](#config-options)) |
|
|
345
|
+
| `open` | `boolean` | Controlled open state |
|
|
346
|
+
| `onSelect` | `(assets: Asset[]) => void` | Selection callback |
|
|
347
|
+
| `onCancel` | `() => void` | Cancel callback |
|
|
348
|
+
| `className` | `string` | CSS class for the wrapper |
|
|
349
|
+
| `style` | `CSSProperties` | Inline styles for the wrapper |
|
|
350
|
+
|
|
351
|
+
### Ref methods
|
|
352
|
+
|
|
353
|
+
| Method | Description |
|
|
354
|
+
|---|---|
|
|
355
|
+
| `open()` | Open the picker imperatively |
|
|
356
|
+
| `close()` | Close the picker imperatively |
|
|
357
|
+
|
|
358
|
+
### Controlled mode
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
362
|
+
|
|
363
|
+
<AssetPicker
|
|
364
|
+
config={config}
|
|
365
|
+
open={isOpen}
|
|
366
|
+
onSelect={(assets) => {
|
|
367
|
+
console.log(assets);
|
|
368
|
+
setIsOpen(false);
|
|
369
|
+
}}
|
|
370
|
+
onCancel={() => setIsOpen(false)}
|
|
371
|
+
/>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Imperative mode
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
const ref = useRef<AssetPickerRef>(null);
|
|
378
|
+
|
|
379
|
+
<button onClick={() => ref.current?.open()}>Open</button>
|
|
380
|
+
<AssetPicker ref={ref} config={config} onSelect={handleSelect} />
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Theming
|
|
386
|
+
|
|
387
|
+
### Brand Color
|
|
388
|
+
|
|
389
|
+
The simplest way to theme the picker is via the `brandColor` config option. It accepts a hex colour string and applies it as the primary accent across all UI elements.
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
picker.config = {
|
|
393
|
+
auth: { /* ... */ },
|
|
394
|
+
brandColor: '#6366f1', // Indigo
|
|
395
|
+
};
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
If not set, the picker uses the brand colour configured in your Scaleflex project settings.
|
|
399
|
+
|
|
400
|
+
### CSS Custom Properties
|
|
401
|
+
|
|
402
|
+
For fine-grained control, override these CSS custom properties on the `<asset-picker>` element or any ancestor. All variables use the `--ap-` prefix.
|
|
403
|
+
|
|
404
|
+
#### Colours
|
|
405
|
+
|
|
406
|
+
| Property | Default | Description |
|
|
407
|
+
|---|---|---|
|
|
408
|
+
| `--ap-primary` | `oklch(0.65 0.19 258)` | Primary accent colour |
|
|
409
|
+
| `--ap-primary-foreground` | `#fff` | Text on primary backgrounds |
|
|
410
|
+
| `--ap-primary-10` | primary @ 10% | Subtle primary tint |
|
|
411
|
+
| `--ap-primary-20` | primary @ 20% | Light primary background |
|
|
412
|
+
| `--ap-background` | `#ffffff` | Main background |
|
|
413
|
+
| `--ap-foreground` | `#09090b` | Main text colour |
|
|
414
|
+
| `--ap-card` | `#ffffff` | Card/panel background |
|
|
415
|
+
| `--ap-border` | `#e4e4e7` | Border colour |
|
|
416
|
+
| `--ap-muted` | `#f4f4f5` | Muted/disabled background |
|
|
417
|
+
| `--ap-muted-foreground` | `#71717a` | Muted/disabled text |
|
|
418
|
+
| `--ap-ring` | same as primary | Focus ring colour |
|
|
419
|
+
| `--ap-selection-bg` | primary @ 8% | Selected item background |
|
|
420
|
+
|
|
421
|
+
#### Modal
|
|
422
|
+
|
|
423
|
+
| Property | Default | Description |
|
|
424
|
+
|---|---|---|
|
|
425
|
+
| `--ap-modal-backdrop` | `rgba(0,0,0,0.5)` | Backdrop overlay colour |
|
|
426
|
+
| `--ap-modal-radius` | `12px` | Modal corner radius |
|
|
427
|
+
| `--ap-modal-shadow` | large shadow | Modal box shadow |
|
|
428
|
+
| `--ap-modal-max-width` | `1200px` | Maximum modal width |
|
|
429
|
+
| `--ap-modal-max-height` | `85vh` | Maximum modal height |
|
|
430
|
+
|
|
431
|
+
#### Typography & Radius
|
|
432
|
+
|
|
433
|
+
| Property | Default | Description |
|
|
434
|
+
|---|---|---|
|
|
435
|
+
| `--ap-font-family` | `system-ui, -apple-system, sans-serif` | Font stack |
|
|
436
|
+
| `--ap-radius` | `8px` | Default border radius |
|
|
437
|
+
| `--ap-radius-sm` | `6px` | Small border radius |
|
|
438
|
+
| `--ap-radius-lg` | `12px` | Large border radius |
|
|
439
|
+
|
|
440
|
+
```css
|
|
441
|
+
asset-picker {
|
|
442
|
+
--ap-primary: #6366f1;
|
|
443
|
+
--ap-primary-foreground: #fff;
|
|
444
|
+
--ap-radius: 12px;
|
|
445
|
+
--ap-modal-max-width: 1400px;
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Filters Reference
|
|
452
|
+
|
|
453
|
+
### Filter Keys
|
|
454
|
+
|
|
455
|
+
These are the keys used in `enabledFilters`, `defaultFilters`, and `forcedFilters`.
|
|
456
|
+
|
|
457
|
+
| Key | Constant | Description |
|
|
458
|
+
|---|---|---|
|
|
459
|
+
| `'type'` | `FILTER_KEYS.TYPE` | File format (image, video, audio, document, archive, font) |
|
|
460
|
+
| `'mimetype'` | `FILTER_KEYS.MIME_TYPE` | MIME type |
|
|
461
|
+
| `'date'` | `FILTER_KEYS.DATE` | Upload/modification date |
|
|
462
|
+
| `'size'` | `FILTER_KEYS.SIZE` | File size range |
|
|
463
|
+
| `'tags'` | `FILTER_KEYS.TAGS` | Asset tags |
|
|
464
|
+
| `'labels'` | `FILTER_KEYS.LABELS` | Asset labels |
|
|
465
|
+
| `'color'` | `FILTER_KEYS.COLOR` | Dominant colour search |
|
|
466
|
+
| `'image'` | `FILTER_KEYS.IMAGE` | Image-specific (resolution, orientation, faces) |
|
|
467
|
+
| `'approval'` | `FILTER_KEYS.APPROVAL` | Approval workflow status |
|
|
468
|
+
| `'metadata'` | `FILTER_KEYS.METADATA` | Custom metadata fields |
|
|
469
|
+
| `'product_ref'` | `FILTER_KEYS.PRODUCT_REF` | Product reference |
|
|
470
|
+
| `'asset_expiration'` | `FILTER_KEYS.LICENSE_EXPIRY` | License/asset expiry date |
|
|
471
|
+
| `'folders'` | `FILTER_KEYS.FOLDERS` | Folder location |
|
|
472
|
+
| `'resolution'` | `FILTER_KEYS.RESOLUTION` | Image resolution |
|
|
473
|
+
| `'orientation'` | `FILTER_KEYS.ORIENTATION` | Image orientation |
|
|
474
|
+
| `'faces'` | `FILTER_KEYS.FACES` | Detected faces count |
|
|
475
|
+
| `'products'` | `FILTER_KEYS.PRODUCTS` | Products |
|
|
476
|
+
|
|
477
|
+
### Filter Data Structures
|
|
478
|
+
|
|
479
|
+
Filters used in `defaultFilters` and `forcedFilters` use these shapes:
|
|
480
|
+
|
|
481
|
+
#### String filter
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
{
|
|
485
|
+
type: 'string',
|
|
486
|
+
values: string[], // Filter values
|
|
487
|
+
operator?: string, // Filter operator (default: ':')
|
|
488
|
+
logic?: 'OR' | 'AND', // Combine logic (default: 'OR')
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
**Examples:**
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
// Only images
|
|
496
|
+
{ type: 'string', values: ['image'] }
|
|
497
|
+
|
|
498
|
+
// Only JPEG and PNG
|
|
499
|
+
{ type: 'string', values: ['image/jpeg', 'image/png'] }
|
|
500
|
+
|
|
501
|
+
// Tagged with "hero" or "banner"
|
|
502
|
+
{ type: 'string', values: ['hero', 'banner'] }
|
|
503
|
+
|
|
504
|
+
// Size range: 1 MB to 50 MB (values in bytes as "min..max")
|
|
505
|
+
{ type: 'string', values: ['1000000..50000000'] }
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
#### Date filter
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
{
|
|
512
|
+
type: 'date',
|
|
513
|
+
field: 'created' | 'updated',
|
|
514
|
+
kind: 'preset' | 'after' | 'before' | 'between' | 'specific' | null,
|
|
515
|
+
preset: string | null, // e.g. 'today', 'last_week', 'last_month'
|
|
516
|
+
from: string | null, // ISO date string
|
|
517
|
+
to: string | null, // ISO date string
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**Examples:**
|
|
522
|
+
|
|
523
|
+
```ts
|
|
524
|
+
// Uploaded in the last month
|
|
525
|
+
{
|
|
526
|
+
type: 'date',
|
|
527
|
+
field: 'created',
|
|
528
|
+
kind: 'preset',
|
|
529
|
+
preset: 'last_month',
|
|
530
|
+
from: null,
|
|
531
|
+
to: null,
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Modified after a specific date
|
|
535
|
+
{
|
|
536
|
+
type: 'date',
|
|
537
|
+
field: 'updated',
|
|
538
|
+
kind: 'after',
|
|
539
|
+
preset: null,
|
|
540
|
+
from: '2025-01-01T00:00:00.000Z',
|
|
541
|
+
to: null,
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Available date presets:** `'today'`, `'last_week'`, `'within_week'`, `'last_month'`, `'within_month'`, `'last_year'`, `'within_year'`, `'empty'`, `'non-empty'`
|
|
546
|
+
|
|
547
|
+
#### Filter operators
|
|
548
|
+
|
|
549
|
+
| Operator | Symbol | Description |
|
|
550
|
+
|---|---|---|
|
|
551
|
+
| `IS` | `:` | Exact match (default) |
|
|
552
|
+
| `EQUAL` | `=` | Equality |
|
|
553
|
+
| `NOT_EQUAL` | `!=` | Inequality |
|
|
554
|
+
| `RANGE` | `..` | Range match |
|
|
555
|
+
| `IS_NOT` | `:-` | Negated match |
|
|
556
|
+
| `IS_EXACT` | `:=` | Strict exact match |
|
|
557
|
+
| `CONTAINS` | `~` | Contains substring |
|
|
558
|
+
| `CONTAINS_IN_TEXT` | `~~~` | Full text search |
|
|
559
|
+
| `STARTS_WITH` | `~^` | Starts with |
|
|
560
|
+
| `GREATER_THAN` | `>` | Greater than |
|
|
561
|
+
| `LESS_THAN` | `<` | Less than |
|
|
562
|
+
| `GREATER_THAN_OR_EQUAL` | `>=` | Greater than or equal |
|
|
563
|
+
| `LESS_THAN_OR_EQUAL` | `<=` | Less than or equal |
|
|
564
|
+
| `SIMILAR_TO` | `~~` | Similarity match |
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## Types Reference
|
|
569
|
+
|
|
570
|
+
All types are exported from the main entry point:
|
|
571
|
+
|
|
572
|
+
```ts
|
|
573
|
+
import type {
|
|
574
|
+
AssetPickerConfig,
|
|
575
|
+
AuthConfig,
|
|
576
|
+
SessionAuth,
|
|
577
|
+
SecurityTemplateAuth,
|
|
578
|
+
Asset,
|
|
579
|
+
Folder,
|
|
580
|
+
FilterKey,
|
|
581
|
+
AnyFilterKey,
|
|
582
|
+
AnyFilter,
|
|
583
|
+
StringFilter,
|
|
584
|
+
DateFilter,
|
|
585
|
+
Filters,
|
|
586
|
+
FiltersState,
|
|
587
|
+
ViewMode,
|
|
588
|
+
SortBy,
|
|
589
|
+
SortDirection,
|
|
590
|
+
TabKey,
|
|
591
|
+
AssetPickerSelectDetail,
|
|
592
|
+
AssetPickerCancelDetail,
|
|
593
|
+
} from '@scaleflex/asset-picker';
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Asset
|
|
597
|
+
|
|
598
|
+
The `Asset` object returned in `ap-select` events:
|
|
599
|
+
|
|
600
|
+
```ts
|
|
601
|
+
interface Asset {
|
|
602
|
+
uuid: string;
|
|
603
|
+
name: string;
|
|
604
|
+
extension: string;
|
|
605
|
+
type: string; // 'image', 'video', 'audio', 'document', ...
|
|
606
|
+
mime?: string; // MIME type
|
|
607
|
+
size: {
|
|
608
|
+
bytes: number;
|
|
609
|
+
pretty: string;
|
|
610
|
+
};
|
|
611
|
+
url?: {
|
|
612
|
+
public: string; // Public URL
|
|
613
|
+
cdn: string; // CDN-optimised URL
|
|
614
|
+
path: string; // Relative path
|
|
615
|
+
permalink?: string; // Permanent link
|
|
616
|
+
};
|
|
617
|
+
created_at: string; // ISO timestamp
|
|
618
|
+
modified_at: string; // ISO timestamp
|
|
619
|
+
tags: Record<string, any>;
|
|
620
|
+
labels: string[];
|
|
621
|
+
meta: {
|
|
622
|
+
title?: string;
|
|
623
|
+
description?: string;
|
|
624
|
+
alt?: string;
|
|
625
|
+
[key: string]: unknown;
|
|
626
|
+
};
|
|
627
|
+
info: {
|
|
628
|
+
img_w?: number; // Image width (px)
|
|
629
|
+
img_h?: number; // Image height (px)
|
|
630
|
+
duration?: number; // Video/audio duration (seconds)
|
|
631
|
+
video_w?: number; // Video width (px)
|
|
632
|
+
video_h?: number; // Video height (px)
|
|
633
|
+
thumbnail?: string; // Thumbnail URL
|
|
634
|
+
main_colors_hex?: string[]; // Dominant colours
|
|
635
|
+
dominant_color_hex?: string; // Most dominant colour
|
|
636
|
+
[key: string]: unknown;
|
|
637
|
+
};
|
|
638
|
+
folder?: {
|
|
639
|
+
uuid: string;
|
|
640
|
+
name: string;
|
|
641
|
+
};
|
|
642
|
+
owner?: {
|
|
643
|
+
uuid: string;
|
|
644
|
+
name: string;
|
|
645
|
+
email: string;
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Folder
|
|
651
|
+
|
|
652
|
+
```ts
|
|
653
|
+
interface Folder {
|
|
654
|
+
uuid: string;
|
|
655
|
+
name: string;
|
|
656
|
+
path: string;
|
|
657
|
+
created_at: string;
|
|
658
|
+
modified_at?: string;
|
|
659
|
+
count?: {
|
|
660
|
+
files_recursive?: number;
|
|
661
|
+
files_direct?: number;
|
|
662
|
+
};
|
|
663
|
+
size?: {
|
|
664
|
+
total_recursive_bytes?: number;
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## Browser Support
|
|
672
|
+
|
|
673
|
+
| Browser | Minimum version |
|
|
674
|
+
|---|---|
|
|
675
|
+
| Chrome | 67+ |
|
|
676
|
+
| Firefox | 63+ |
|
|
677
|
+
| Safari | 13.1+ |
|
|
678
|
+
| Edge (Chromium) | 79+ |
|
|
679
|
+
|
|
680
|
+
Requires native support for Custom Elements v1, Shadow DOM, and ES2020+. Internet Explorer is **not** supported.
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
## License
|
|
685
|
+
|
|
686
|
+
**PROPRIETARY** — All Rights Reserved.
|
|
687
|
+
|
|
688
|
+
Copyright © 2025 [Scaleflex SAS](https://www.scaleflex.com).
|
|
689
|
+
|
|
690
|
+
This software and associated documentation are the exclusive property of Scaleflex SAS. No part of this software may be copied, modified, distributed, sublicensed, sold, or otherwise made available to any third party without prior written permission from Scaleflex SAS.
|
|
691
|
+
|
|
692
|
+
This package is distributed via npm solely for the convenience of licensed customers. Installing or using this package does not grant any licence to use the software. Use is permitted only under a separate written licence agreement with Scaleflex SAS.
|
|
693
|
+
|
|
694
|
+
Unauthorised use, reproduction, or distribution of this software may result in civil and criminal penalties and will be prosecuted to the maximum extent permitted by law.
|
|
695
|
+
|
|
696
|
+
For licensing enquiries, contact [sales@scaleflex.com](mailto:sales@scaleflex.com).
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
<p align="center">
|
|
701
|
+
Made with care by <a href="https://www.scaleflex.com">Scaleflex</a>
|
|
702
|
+
</p>
|