npm package: @scaleflex/widget-core
Description: Core module for the extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, Box, One Drive, S3 and more.
Latest version: 4.8.13

# Scaleflex Media Asset Widget (SMAW)


> This is the successor of [Filerobot Media Asset Widget (FMAW) - V3](https://www.npmjs.com/package/@filerobot/core).


[![Plugins][plugins-image]](#plugins)
[![Website][filerobot-image]][sfx-url]
[![Version][filerobot-version]][version-url]
[![Version][filerobot-version-latest]][version-url-latest]
[![Version][filerobot-version-stable]][version-url-stable]
[![Scaleflex team][made-by-image]][sfx-url]
[![License][license-image]][license-url]
[![CodeSandbox][codeSandbox-image]][codeSandbox-url]

<div align='center'>
<img title="Scaleflex Widget logo" alt="Scaleflex Widget logo" src="https://assets.scaleflex.com/Corporate%20Branding/%5B2025%5D%20ALL%20LOGOS%20+%20ICONS/SCALEFLEX/VXP%20logo/Horizontal%20Black/VXP%20logo%20BLACK.png?vh=13b506&w=300" width="300"/>
</div>

<details>
  <summary>Table of contents</summary>

- [What is the SMAW?](#what-is-the-smaw)
  - [Installation (minimal drag and drop upload zone)](#installation-minimal-drag-and-drop-upload-zone)
    - [ReactJS (over package manager)](#reactjs-over-package-manager)
    - [Vanilla JS (over CDN link, containing all plugins)](#vanilla-js-over-cdn-link-containing-all-plugins)
  - [Widget modes and use cases](#widget-modes-and-use-cases)
  - [Core package and plugins](#core-package-and-plugins)
- [Quick Start](#quick-start)
  - [Uploader mode (as modal to upload files in the Scaleflex DAM)](#uploader-mode-as-modal-to-upload-files-in-the-scaleflex-dam)
    - [Enabling upload connectors for import from external storage sources](#enabling-upload-connectors-for-import-from-external-storage-sources)
    - [Adding the progress panel](#adding-the-progress-panel)
    - [Customizing the Uploader and listening to events](#customizing-the-uploader-and-listening-to-events)
  - [Asset Picker mode (for searching and selecting assets from the Scaleflex DAM)](#asset-picker-mode-for-searching-and-selecting-assets-from-the-scaleflex-dam)
    - [Inserting selected selected assets into your application](#inserting-selected-selected-assets-into-your-application)
    - [Customizing the Asset Picker experience](#customizing-the-asset-picker-experience)
  - [Asset Manager mode (light DAM)](#asset-manager-mode-light-dam)
- [Documentation (Core package)](#documentation-core-package)
  - [ReactJS (over package manager)](#reactjs-over-package-manager-1)
    - [Installation](#installation)
    - [Usage](#usage)
  - [Vanilla JS (over CDN link, containing all plugins)](#vanilla-js-over-cdn-link-containing-all-plugins-1)
    - [Installation](#installation-1)
    - [Usage](#usage-1)
  - [Parameters](#parameters)
    - [General parameters relevant for all modes](#general-parameters-relevant-for-all-modes)
    - [Uploader-related properties](#uploader-related-properties)
    - [Events and Callbacks](#events-and-callbacks)
    - [Plugin APIs (advanced use)](#plugin-apis-advanced-use)
  - [License](#license)
</details>

# What is the SMAW?

The **Scaleflex Media Asset Widget (SMAW)** is a combined file uploader and media library browser. It is the user-facing gateway to your Scaleflex Digital Asset Management (DAM), allowing users to upload files into a central storage or search in the DAM library, all through a unified widget from your host application.  
It can be extended and customized by a robust ecosystem of [plugins](#user-content-core-package-and-plugins).

> Check out the <a href="https://scaleflex.cloudimg.io/v7/plugins/widget/v4/demo/index.html?func=proxy" target="_blank" rel="noopener noreferrer">interactive sandbox</a> to try the different widget modes and play with its parameters.

> You need a Scaleflex DAM account to use the SMAW. Get one <a href="https://www.scaleflex.com/filerobot-free-trial" target="_blank" rel="noopener noreferrer">here</a> for free.

**Key features:**

- **Flexible file upload:** users can upload single or multiple files into the Scaleflex DAM tenant via drag & drop, copy-paste, or file picker. The widget supports advanced sources (Device camera or screen recording) as well as third-party integrations (Google Drive, Dropbox, OneDrive, Instagram, Facebook, etc.) for uploading.
- **Media library & asset management:** provides a built-in file explorer and media gallery with folder navigation, searching by tags/metadata, asset preview, and basic file operations (rename, move, delete, etc.). Users can even download multiple files as a ZIP and view version history for assets.
- **Inline Editing & Processing:** includes optional plugins like the `@scaleflex/widget-image-editor` for editing images (crop, resize, filters, etc.) directly in the browser, as well as video processing or transformations on the fly.
- **Collaboration & Sharing:** files uploaded via the widget are immediately available in the DAM, with accelerated delivery links (CDN URLs) for sharing. Features like AI-powered tagging, commenting/annotations on images, and usage rights metadata can be enabled to enrich collaboration.

The widget is highly **configurable** and **modular** – plugins are optional for additional functionality, keeping it lightweight. It can be rendered inline in a page element, or as a pop-up modal triggered by user action, such as a button click.

## Installation (minimal drag and drop upload zone)

The minimal setup to display the widget as a drag and drop upload zone requires the `@scaleflex/widget-core` ([**Core**](https://www.npmjs.com/package/@scaleflex/widget-core#documentation)), `@scaleflex/widget-explorer` ([**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer)) and `@scaleflex/widget-xhr-upload` ([**Uploader**](https://www.npmjs.com/package/@scaleflex/widget-xhr-upload)) packages.

Below is a simple installation example in both ReactJS and Vanilla JS.

### ReactJS (over package manager)

npm

```bash
npm install --save @scaleflex/widget-core @scaleflex/widget-explorer @scaleflex/widget-xhr-upload
```

yarn

```bash
yarn add @scaleflex/widget-core @scaleflex/widget-explorer @scaleflex/widget-xhr-upload
```

Sample code to instantiate the widget:

```js
import { useEffect, useRef } from 'react';
import ScaleflexWidget from '@scaleflex/widget-core';
import Explorer from '@scaleflex/widget-explorer';
import XHRUpload from '@scaleflex/widget-xhr-upload';

// Import base styles (Core first, then Explorer - included in the packages above)
import '@scaleflex/widget-core/dist/style.min.css';
import '@scaleflex/widget-explorer/dist/style.min.css';

function App() {
  const scaleflexWidgetRef = useRef(null);

  useEffect(() => {
    // Initialize the core widget
    scaleflexWidgetRef.current = ScaleflexWidget({
      container: "YOUR_CONTAINER",
      securityTemplateId: "YOUR_SECURITY_TEMPLATE_ID"
    });
    
    // Use the Explorer UI in default uploader mode, and enable XHR upload
    scaleflexWidgetRef.current
      .use(Explorer, { target: "#widget-container", inline: true })
      .use(XHRUpload);

    // Cleanup on unmount (close widget to free resources)
    return () => scaleflexWidgetRef.current.close();
  }, []);

  return <div id="widget-container" style={{ width: '800px', height: '600px' }}></div>;
}

export default App;
```

In the example above, the Explorer plugin is configured with `inline: true` and a DOM element `#widget-container` as its target. This widget will be rendered inline in that element (as opposed to a modal). The XHRUpload plugin is enabled with default settings to handle file uploads trough the Scaleflex DAM API.

### Vanilla JS (over CDN link, containing all plugins)

- add the following CSS file before the end of `</head>` in your `HTML` file

```html
<link
  rel="stylesheet"
  type="text/css"
  href="https://cdn.scaleflex.com/plugins/widget/v4/stable/scaleflex-widget.min.css"
/>
```

- add the following JS file before the end of `</body>` in your `HTML` file.

```html
<script
  type="text/javascript"
  src="https://cdn.scaleflex.com/plugins/widget/v4/stable/scaleflex-widget.min.js"
></script>
```

Sample code to instantiate the widget:

```html
<!-- Include CSS in <head> -->
<link rel="stylesheet" href="https://cdn.scaleflex.com/plugins/widget/v4/stable/scaleflex-widget.min.css" />

<!-- Container element for the widget -->
<div id="widget-container"></div>

<!-- Include JS in <body> -->
<script src="https://cdn.scaleflex.com/plugins/widget/v4/stable/scaleflex-widget.min.js"></script>
<script>
  // Access global widget object
  const Widget = window.ScaleflexWidget;
  // Initialize core
  const scaleflexWidget = Widget.Core({
    container: "YOUR_CONTAINER",
    securityTemplateId: "YOUR_SECURITY_TEMPLATE_ID",
    // dev: false
  });
  // Add plugins
  scaleflexWidget
    .use(Widget.Explorer, { target: "#widget-container", inline: true })
    .use(Widget.XHRUpload);
</script>
```

This achieves the same outcome as the ReactJS example: an inline file explorer/uploader within the `#widget-container` div.

> In production, you might load the widget only when needed (e.g., on a button click, or in a modal). The above examples instantiate it immediately for simplicity. Also ensure you include the CSS file *before* the JS file to properly load styles.

## Widget modes and use cases

The SMAW supports multiple **modes** to fit different use cases:

- **Uploader**: *File upload interface (default mode).* Enables your users to upload files to your DAM. The widget shows an upload panel (with drag & drop zone) and optionally allows selecting sources (local files or connected cloud sources).  
Use case: a web app where users upload media (images/videos) or documents (UGC) into a central library.  
[Demo & Example code](https://scaleflex.cloudimg.io/v7/plugins/widget/v4/demo/index.html?func=proxy#uploader-section)

- **Asset Picker**: *Media selector dialog.* Enables your users to browse existing assets in the DAM (without the ability to modify or delete them) and select one or more assets for use in the application the widget is integrated into.  
Use case: content editors or e-commerce managers working in a CMD search for product assets in the DAM and insert them into an editorial page or product details page.  
[Demo & Example code](https://scaleflex.cloudimg.io/v7/plugins/widget/v4/demo/index.html?func=proxy#assets-picker-section)

- **Asset Manager (aka Light DAM)**: *Embedded light DAM library.* Enables a lightweight DAM experience inside your application – users can navigate folders and files, upload new files, add tags, edit metadata and move/rename/delete assets.  
Use case: users of your application need DAM-like functionality to upload and tag assets, set their metadata and view advanced information before using assets.  
[Example code](#asset-manager-mode-light-dam)

## Core package and plugins

The SMAW is built as a modular system of packages. To get started, you’ll need the `@scaleflex/widget-core` [**Core**](https://www.npmjs.com/package/@scaleflex/widget-core#documentation) and `@scaleflex/widget-explorer` [**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer) packages. From there, you can extend the widget’s capabilities with a range of optional packages that add extra functionality.

- `@scaleflex/widget-core` (aka [**Core**](https://www.npmjs.com/package/@scaleflex/widget-core#documentation)) REQUIRED : this Core handles initialization, global settings, and communication with the Scaleflex DAM API. You always start by creating the core widget instance with the identifier of your *DAM container* (aka project token) and *security credentials*.
- `@scaleflex/widget-explorer` (aka [**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer)) REQUIRED: the Explorer provides the main file explorer interface (thumbnails, folder tree, etc.) and implements the various [modes](https://scaleflexhq.atlassian.net/wiki/spaces/FIL/pages/1677557765/Scaleflex+Media+Asset+Widget+SMAW#%5BinlineExtension%5DModes-and-Use-Cases) mentioned above. (Uploader/Picker/Manager). Following UI plugins are automatically imported for extra functionality:
  - `@scaleflex/widget-progress-panel` (aka [**Progress Panel**](https://www.npmjs.com/package/@scaleflex/widget-progress-panel)) OPTIONAL: a multi-functional progress bar to show upload/download progress
  - `@scaleflex/widget-image-editor` (aka [**Image Editor**](https://www.npmjs.com/package/@scaleflex/widget-image-editor)) OPTIONAL: a web-based image editor for basic edits (resize, crop, remove background, expand background with AI, remove objects with AI, …). This plugin is powered by the open-source [Scaleflex Image Editor](https://github.com/scaleflex/filerobot-image-editor#readme) plugin.
- `@scaleflex/widget-xhr-upload` (aka [**Uploader**](https://www.npmjs.com/package/@scaleflex/widget-xhr-upload)) OPTIONAL: the Uploader provides an UI interface (modal or drag and drop zone) to upload files in the Scaleflex DAM from your host application. It perform standard HTTPS multipart uploads agains the Scaleflex DAM API. Following optional UI plugins for extra functionality are available:
  - `@scaleflex/widget-webcam` (aka [**Webcam**](https://www.npmjs.com/package/@scaleflex/widget-webcam)) OPTIONAL: enables the user to capture photos/videos with his camera and upload them into the DAM
  - `@scaleflex/widget-screen-capture` (aka [**Screen Capture**](https://www.npmjs.com/package/@scaleflex/widget-screen-capture)) OPTIONAL: enables the user to screenshot or record his screen and upload the resulting image or video into the DAM
  - `@scaleflex/widget-url` (aka [**Url**](https://www.npmjs.com/package/@scaleflex/widget-image-editor)): enables the user to import an asset from an external URL link
  - **Upload connectors** OPTIONAL: these connectors enable users to import files from external storage providers, such as Box, Dropbox, Google Drive, OneDrive, etc. Users will need to authenticate with their accounts to the 3rd party service using oAuth:
    - [Box](https://www.npmjs.com/package/@scaleflex/widget-box)
    - [Dropbox](https://www.npmjs.com/package/@scaleflex/widget-dropbox)
    - [Facebook](https://www.npmjs.com/package/@scaleflex/widget-facebook)
    - [Google Drive](https://www.npmjs.com/package/@scaleflex/widget-google-drive)
    - [Instagram](https://www.npmjs.com/package/@scaleflex/widget-instagram)
    - [OneDrive](https://www.npmjs.com/package/@scaleflex/widget-onedrive)
    - [Canva](https://www.npmjs.com/package/@scaleflex/widget-canva): enables the user to open the Canva editor inside your application and import a design into the widget for uploading into the DAM.
    - [Unsplash](https://www.npmjs.com/package/@scaleflex/widget-unsplash): enables the user to search free images and videos in the Unsplash stock library and import them into the widget for uploading into your DAM
- `@scaleflex/widget-tus` (aka **tus Uploader**): enable resumable/chunked uploads. Recommended if users need to upload many files or very large files (> 1 Gb) into the Scaleflex DAM. This requires activation by Scaleflex on your DAM tenant, please [contact support](mailto:hello@scaleflex.com).


# Quick Start

Before implementing the SMAW, ensure you have the following Scaleflex DAM credentials ([here](https://www.scaleflex.com/filerobot-free-trial) to get some for free !).

- **Container** (aka project token)**:** a Scaleflex DAM *container* (project) name or token. This identifies the DAM tenant where assets will be uploaded or fetched. You can create a project and get the container token from the [Scaleflex Asset Hub](https://hub.scaleflex.com/) (requires a Scaleflex account).
- **Security Template ID:** ID of a Security Template defined in your DAM. This is required for authentication – the widget uses it to request a temporary access token with specific permissions to interact with the DAM. Create a Security Template [here](https://hub.scaleflex.com/settings/project/access/security-templates) (requires a Scaleflex account) and define its scope (like OAuth2 scopes). Make sure the Security Template grants the rights needed for your use case (e.g. upload rights for Uploader mode, list/view rights for Asset Picker mode, etc.).

## Uploader mode (as modal to upload files in the Scaleflex DAM)

> Use case: a web app where users upload media (images/videos) or documents (UGC) into a central library.

You can implement the SMAW in **Uploader** mode in two ways:

- **as a modal:** the widget opens when triggered (e.g., by a button), and appears as a modal
- **inline embedded in page:** the widget is always visible in a given page section, acting as an upload panel or drop zone

By default (`inline: false`), the [**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer) plugin will display as a modal. You must provide a trigger selector in the [**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer) options to open the modal on user action. For example, you might have a button in your HTML:

```html
<!-- ... -->
  <button id="open-uploader">Upload Assets</button>
<!-- ... -->
```

Add the following code to the widget’s instantiation:

```js
// ...
  scaleflexWidget.use(Explorer, { 
    trigger: "#open-uploader",     // CSS selector for the trigger element
    target: "body"                // where to attach the modal in the DOM
  }); 
// ...
```

Now, when the user clicks op the *Upload Assets* button, the widget modal will open in the middle of the page. The trigger can be any (or multiple) valid selectors. In this example the target is *body*, but usually it will be a specific DOM element in your page.

While the modal is open, users can drag and drop files in the modal for upload or select form their device. No additional plugins (such as [Google Drive](https://www.npmjs.com/package/@scaleflex/widget-google-drive), [Box](https://www.npmjs.com/package/@scaleflex/widget-box) or [Unsplash](https://www.npmjs.com/package/@scaleflex/widget-unsplash)) are enabled in this example.

### Enabling upload connectors for import from external storage sources

To enable import from [Google Drive](https://www.npmjs.com/package/@scaleflex/widget-google-drive), [Box](https://www.npmjs.com/package/@scaleflex/widget-box) or [Unsplash](https://www.npmjs.com/package/@scaleflex/widget-unsplash), etc., you need to add the relevant **Upload connectors**:

```js
import { useEffect, useRef } from 'react';
import ScaleflexWidget from '@scaleflex/widget-core';
import Explorer from '@scaleflex/widget-explorer';
import XHRUpload from '@scaleflex/widget-xhr-upload';
import GoogleDrive from '@scaleflex/widget-google-drive';
import Box from '@scaleflex/widget-box';
import Unsplash from '@scaleflex/widget-unsplash';
// ... other imports ...

import '@scaleflex/widget-core/dist/style.min.css';
import '@scaleflex/widget-explorer/dist/style.min.css';

// ...

scaleflexWidget
  .use(Explorer, { 
    trigger: "#open-uploader",
    target: "#widget-container"
    })
  .use(XHRUpload)
  .use(GoogleDrive)
  .use(Box)
  .user(Unsplash);

// ...
```

Each connector, when added, will introduce a new option in the UI that enables users to log in to that service and pick files to import. Available **Upload connectors** are listed [here](https://scaleflexhq.atlassian.net/wiki/spaces/FIL/pages/1677557765/Scaleflex+Media+Asset+Widget+SMAW#Architecture-Overview).

> External storage sources may require additional configuration (such as API keys or client IDs for the third-party service). Refer to the specific storage source page for setup instructions.

### Adding the progress panel

An upload without progress is not very user friendly, it is time to add the [**Progress Panel**](https://www.npmjs.com/package/@scaleflex/widget-progress-panel) plugin:

```js
import GoogleDrive from '@scaleflex/widget-google-drive';
import Dropbox from '@scaleflex/widget-box';
import Dropbox from '@scaleflex/widget-unsplash';
import ProgressPanel from '@scaleflex/widget-progress-panel';
// ... other imports ...

import '@scaleflex/widget-core/dist/style.min.css';
import '@scaleflex/widget-explorer/dist/style.min.css';

scaleflexWidget
  .use(Explorer, { 
    trigger: "#open-uploader",
    target: "#widget-container"
    })
  .use(XHRUpload)
  .use(ProgressPanel)
  .use(GoogleDrive)
  .use(Dropbox);
  
// ...
```

### Customizing the Uploader and listening to events

To customize the upload experience, you can use optional parameters from [Explorer](https://www.npmjs.com/package/@scaleflex/widget-core#properties) and [Uploader](https://www.npmjs.com/package/@scaleflex/widget-xhr-upload#properties), for example:

- target folder through [*uploadToFolderPath*](https://www.npmjs.com/package/@scaleflex/widget-xhr-upload#uploadToFolderPath)
- upload limits and file format restrictions through [*restrictions*](https://www.npmjs.com/package/@scaleflex/widget-core#restrictions)

When the upload is completed, you can be notified via the `upload-success` event hook. The widget fires multiple events listed [here](https://www.npmjs.com/package/@scaleflex/widget-core#events-and-callbacks).

## Asset Picker mode (for searching and selecting assets from the Scaleflex DAM)

> Use case: content editors or e-commerce managers working in a CMD search for product assets in the DAM and insert them into an editorial page or product details page.

The **Asset Picker** mode focuses on searching, selecting, and inserting files from your Scaleflex DAM into your host application. Typical scenarios include a user choosing one or more existing image from from the DAM and to inserting them into a blog post.

To enable **Asset Picker** mode, you need to use the [**ExploreView**](https://www.npmjs.com/package/@scaleflex/widget-explorer) component as `ExploreViewComponent: ExploreView` and set the `useAssetsPicker: true` flag in the plugin’s configuration:

```js
...
  scaleflexWidget.use(Explorer, {
    trigger: "#open-uploader",
    target: "#widget-container"
    ExploreViewComponent: ExploreView,
    useAssetsPicker: true,
    disableUpload: true // prevents users from uploading assets
    // hideDownloadButtonIcon: true,  // optionally hide download button in UI to prevent users from downloading assets
  });
...
```

In this mode, users can search for assets, browse the folder hierarchy and insert one or multiple assets into the host application. Advanced functionality such as asset details view (to view metadata or variations), metadata editing or rename/move/delete are not available in this mode.

> If using the Vanilla JS, then the ExploreViewComponent is accessible via the global object as well (e.g. `window.ScaleflexWidget.Explorer.ExploreViewComponent`).

### **Inserting selected selected assets into your application**

Once the user picks one or multiple file and clicks on the *Insert* button, the widget will trigger an event to deliver those files to your application. You can listen for the `export` event to catch the file details. For example:

```js
...
  scaleflexWidget.on('export', (files) => {
    // 'files' is an array of selected file objects
    console.log("User selected assets:", files);
    // You can then use file URLs or metadata from these objects as needed
  });
...
```

In ReactJS, you might instead provide a callback via props or context, but using the `.on('export', ...)` event listener works universally. Each file object will contain details like URL, name, size, metadata, etc., which you can then use in your application to for example insert the image into an `<img>` tag.

### Customizing the Asset Picker experience

You can use optional parameters from the [Explorer](https://www.npmjs.com/package/@scaleflex/widget-core#properties) plugin, for example:

- set a limit on the amount of selectable files through [*maxCountOfSelectedFiles*](https://www.npmjs.com/package/@scaleflex/widget-explorer#maxCountOfSelectedFiles)
- prevent the user from downloading the file on his device through [*hideDownloadButtonIcon*](https://www.npmjs.com/package/@scaleflex/widget-explorer#hideDownloadButtonIcon)

When the upload is completed, you can be notified via the `upload-success` event hook. The SMAW provides multiple events listed [here](https://www.npmjs.com/package/@scaleflex/widget-core#events).

> Like in other modes, the Asset Picker respects the permissions defined in security template – e.g., if the token is read-only, the UI will naturally prevent any file modification such as rename or delete.

## Asset Manager mode (light DAM)

> Use case: users of your application need DAM-like functionality to upload and tag assets, set their metadata and view advanced information before using assets.

The **Asset Manager** mode allows the SMAW to function as a light DAM interface embedded in your application (think *DAM as iframe in your application but without any top-level menus and settings*). It is based on the functionality of the Asset Picker but adds file details (such as versions, metadata, and variations) and enables editing. The [**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer) will display a directory tree and file library, letting the user browse through folders and view assets. Basic digital asset management operations are available and are based on the user’s permissions in the DAM: editing file metadata, moving files, creating folders, uploading new files into the library, etc. This is useful for applications that need to give users a way to manage their media library without leaving the host application.

To enable **Asset Manager** mode, you need to use the [**ExploreView**](https://www.npmjs.com/package/@scaleflex/widget-explorer) component as `ExploreViewComponent: ExploreView` and set the `useAssetsPicker: false` flag in the plugin’s configuration:

```js
...
import ExploreView from '@scaleflex/widget-explorer/lib/components/ExploreView';
...
scaleflexWidget.use(Explorer, { 
  target: '#asset-browser', 
  inline: true,
  ExploreViewComponent: ExploreView, // set this to enable Asset Manager mode
  useAssetsPicker: false,
  hideDownloadButtonIcon: false,
  // disableUpload: true // if true, the upload functionality won't be available
});
...
```

Users can also upload new files to the Scaleflex DAM via the *Upload* button, which is displayed default. It can be hidden through the [*disableUpload*](https://www.npmjs.com/package/@scaleflex/widget-explorer#disableUpload) parameter.

> `useAssetsPicker` governs wether the widget will be in Asset Picker (`useAssetsPicker: true`) mode or Asset Manager (`useAssetsPicker: false`) mode.

> Use case: building a *Media Library* page or tab within an admin panel where users manage company files and assets. They can browse all the company’s images, edit tags or metadata, and upload replacements.

# Documentation (Core package)

## ReactJS (over package manager)

### Installation

npm

```bash
npm install --save @scaleflex/widget-core
```

yarn

```bash
yarn add @scaleflex/widget-core
```

### Usage

```js
import ScaleflexWidget from '@scaleflex/widget-core'
import "@scaleflex/widget-core/dist/style.min.css";

...
...
...

const scaleflexWidget = ScaleflexWidget(propertiesObject)
```

## Vanilla JS (over CDN link, containing all plugins)

### Installation

- add the following CSS file before the end of `</head>` in your `HTML` file

```html
<link
  rel="stylesheet"
  type="text/css"
  href="https://cdn.scaleflex.com/plugins/widget/v4/stable/scaleflex-widget.min.css"
/>
```

- add the following JS file before the end of `</body>` in your `HTML` file.

```html
<script
  type="text/javascript"
  src="https://cdn.scaleflex.com/plugins/widget/v4/stable/scaleflex-widget.min.js"
></script>
```

### Usage

```js
const scaleflexWidgetCore = window.ScaleflexWidget.Core
...
...
...
const scaleflexWidget = scaleflexWidgetCore(propertiesObject)
```

## Parameters

### General parameters relevant for all modes

**container**  
Type: `string` (required)  
Default: `undefined`  
The Scaleflex DAM project token (e.g. *fhlcusomb*), [here](https://www.scaleflex.com/filerobot-free-trial) to get one for free.

**securityTemplateId**  
Type: `string` (required)  
Default: `undefined`  
The Id of a Security Template generated in the [Scaleflex DAM Access settings](https://hub.scaleflex.com/settings/project/access/security-templates). The Security Template defines permissions and restrictions similar to OAuth2 scopes and is used by the widget to customize its UI functions.

**id**

Type: `string`  
Default: `'scaleflexWidget'`  
Unique identifier for the widget instance (used in HTML selector).

**theme**  
Type: `object`  
Default: `{ palette: {...}, breakpoints: {...}, typography: {...}, shadows: {...} }`  
Custom theme overrides for palette, breakpoints, typography, and shadows. The [**@scaleflex/ui**](https://github.com/scaleflex/ui/tree/master/packages/ui/src/theme) is used as a global theme. Default values for the properties are linked below:

- [color palette](https://github.com/scaleflex/ui/blob/master/packages/ui/src/theme/roots/palette/entity/default-palette.ts)
- [typography](https://github.com/scaleflex/ui/blob/master/packages/ui/src/theme/roots/typography/entity/default-typography.ts)
- [breakpoints](https://github.com/scaleflex/ui/blob/master/packages/ui/src/theme/roots/breakpoints/entity/default-breakpoints.ts)
- [shadows](https://github.com/scaleflex/ui/blob/master/packages/ui/src/theme/roots/shadows/entity/default-shadows.ts)

Sample override below:

```js
theme: {
    palette: {
     "accent-primary": "#479898",
     "accent-primary-hover": "#479898",
     "accent-primary-active": "#479898",
     "accent-stateless": "#479898",
     "link-pressed": "#479898",
     "border-active-bottom": "#479898"
   },
   typography: {
      "title-h6": {
        fontWeight: FontWeight.Medium, // 500
        fontSize: '12px',
        lineHeight: '18px',
      },
   },
   breakpoints: {
     values: {
       xs: 0,
       md: 900,
       xl: 1400
     }
   },
   shadows: {
     "shadow-sm": '6px -4px 12px 0px rgba(146, 166, 188, 0.14)'
   }
}
```

**language** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `string`  
Default: `'en'`  
Language code for widget UI.

**locale** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `object`  
Default: Default locale from `lib/defaultLocale.js`  
Override UI labels via object (e.g. `{ strings: { loaderLoadingLabel: 'Loading' } }`).

**debug** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `boolean`  
Default: `false`  
Turns on the debug mode by exposing the plugin's debug information to the global window object and turns on the logger.

**logger** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `object`  
Default:

```js
errorsLogger = {
  debug: (...args) => {},
  warn: (...args) => {},
  error: (...args) => console.error(`[Scaleflex] [${getTimeStamp()}]`, ...args),
};
```

Custom logger object for logging messages.

### Uploader-related properties

**autoProceed** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `boolean`  
Default: `false`  
If `true`, upload process starts immediately after selecting/dropping files.

**allowMultipleUploads** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `boolean`  
Default: `true`  
Allows simultaneous multiple file uploads.

**restrictions** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `object`  
Default:

```js
restrictions: {
  "maxFileSize": null,
  "maxTotalFilesSize": null,
  "hideRestrictionsInformer": null,
  "maxNumberOfFiles": null,
  "minNumberOfFiles": null,
  "allowedFileTypes": null,
  "maxItemsSizeForCompression": null,
  "remoteMaxFolderImportCount": 500,
  "remoteMaxFolderImportSize": 10737418240,
  "remoteMaxFolderDepth": 5,
  "remoteMaxFolderCount": 100
}
```

Restrictions relevant to Uploader mode:

| Property                   | Type                | Default | Description                                                                |
| -------------------------- | ------------------- | ------- | -------------------------------------------------------------------------- |
| `maxFileSize`              | `number` \| `null`  | `null`  | maximum file size in bytes                                                 |
| `maxTotalFilesSize`        | `number` \| `null`  | `null`  | maximum files size in megabyte                                             |
| `hideRestrictionsInformer` | `boolean` \| `null` | `null`  | hide restrictions informer message                                         |
| `maxNumberOfFiles`         | `number` \| `null`  | `null`  | maximum number of files to be uploaded simultaneously                      |
| `minNumberOfFiles`         | `number` \| `null`  | `null`  | minimum number of files before upload can start                            |
| `allowedFileTypes`         | `array` \| `null`   | `null`  | accepted file types or extensions, eg. `['image/*', 'image/jpeg', '.jpg']` |

Constraints for importing folders from Upload connectors (external storages providers such as [Google Drive](https://www.npmjs.com/package/@scaleflex/widget-google-drive), [Box](https://www.npmjs.com/package/@scaleflex/widget-box) or [Unsplash](https://www.npmjs.com/package/@scaleflex/widget-unsplash), etc.):

| Property                     | Type               | Default       | Description                                                              |
| ---------------------------- | ------------------ | ------------- | ------------------------------------------------------------------------ |
| `remoteMaxFolderImportCount` | `number` \| `null` | `500`         | maximum number of files to import from folders                           |
| `remoteMaxFolderImportSize`  | `number` \| `null` | `10737418240` | remote upload maximum total size of files to import from folders (bytes) |
| `remoteMaxFolderDepth`       | `number` \| `null` | `5`           | remote upload maximum folder depth level for recursive folder imports    |
| `remoteMaxFolderCount`       | `number` \| `null` | `100`         | remote upload maximum number of folders that can be selected for upload  |

**customUploadedFilesSizeInMb** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `number`  
Default: `0`  
A number to consider (add) to the already uploaded files size while checking the restrictions with the maxTotalFilesSize.

**onBeforeFileAdded** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `function`  
Default: `(currentFile, files) => currentFile`  
Hook to validate or transform files before they’re added:

- if the function returns `true`, the file is added to the state
- if the function returns a modified `file` object the returned object would be added to the state
- if the function returns `false`, the file is not added to the state

**onBeforeUpload** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  
Type: `function`  
Default: `(files) => files`  
Hook before upload starts; can cancel or modify files:

- if the function returned `true` the upload would start
- if returned `files` object the returned object would be processed
- if returned `false` the uploading process won't start

### Events and Callbacks

After configuring the widget, you’ll likely interact with it via **events**. The widget instance (*scaleflexWidget*) is an event emitter. You can subscribe to events using `scaleflexWidget.on('<event-name>', callback)`. Some useful events include:

- **upload**: fired when an upload process is initiated (e.g., user clicks Upload button).
- **upload-started**, **upload-progress**, **upload-success**, **upload-error**: for tracking individual file upload status. For example, upload-success provides the file and server response when a file finishes uploading.
- **complete**: fired when a batch of uploads is fully done (all files either succeeded or failed).
- **file-added**, **file-removed**: when a user adds a file to the queue or removes it before upload.
- **restriction-failed**: when a file is rejected due to restrictions (size/type limits).
- **explorer:modal-open**, **explorer:modal-close**: when the modal is opened or closed.
- **export**: when files are selected in Asset Picker mode and "exported" (i.e., the user confirmed selection).
- **error** (global): if any unexpected error occurs.

> All of them are supported from  ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Using these events, you can integrate the widget deeply into your application’s workflow (e.g., show a toast when uploads complete, refresh your content after an image is inserted, etc.). For a full list of events, refer to the documentation below:

**file-added** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when a file has been added to the selected files for uploading.

`params`:

- `file`: The file object whom thumbnail is generated.

example

```js
scaleflexWidget.on("file-added", (file) => {
  console.log("The new file object which is added:", file);
});
```

**file-removed** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when a file has been removed from the selected files for uploading.

`params`:

- `file`: The file object removed.
- `deletionReason`: The reason for deleting the file or from where the deletion has done might be provided or not.

example

```js
scaleflexWidget.on("file-removed", (file, reason) => {
  console.log(
    `The file ${file.name} is removed because ${reason}, file's object:`,
    removedFile
  );
});
```

**upload** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on creating a new upload process.

`params`:

- `object`: An object contains both the uploading process id and the the files ids for files to be uploaded, ex. `{ id: uploadId, filesIds: fileIds, files }`.

example

```js
scaleflexWidget.on("upload", (uploadProcess) => {
  console.log("Upload started with upload id: ", uploadProcess.id);
  console.log("Contains the following file ids", uploadProcess.filesIds);
});
```

**restriction-failed** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when the restriction checking is failed and there is a file not meeting the restrictions.

`params`:

- `file`: The file object that has failed the check.
- `error`: The error faced/fired during the check.

example

```js
scaleflexWidget.on("restriction-failed", (file, error) => {
  console.log("Couldnt process the following file object", file);
  console.log("As the following error fired:", error);
});
```

**upload-started** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when upload is started.

`params`:

- `file`: The file object that started uploading.
- `started`: An object contains upload Id, ex. `{ uploadId: upload id assigned to current file }`.

**upload-progress** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted with the upload progress.

`params`:

- `file`: The file object that has some progress in its uploading.
- `progress`: An object containing the progress of the file being uploaded, ex. `
{ filerobot: plugin's instance, bytesFinished: 1500, bytesTotal: 3500, uploadId: upload id assigned to current file }.
`

example

```js
scaleflexWidget.on("upload-progress", (file, progress) => {
  console.log("The following file object progressed", file);
  console.log("The progress object is as following", progress);
});
```

**upload-success** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when a file is successfully uploaded.

`params`:

- `file`: The file object that has uploaded.
- `response`: The upload request response received.
- `options`: object that contains the uploadId

example

```js
scaleflexWidget.on("upload-success", (file, response, { uploadId }) => {
  console.log(
    `The ${file.name} with the object ${file} is uploaded ${uploadId} and the whole response`,
    response
  );
});
```

**upload-error** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when a file faced some error/issue while uploading.

`params`:

- `file`: The file object which fired the error.
- `error`: object that contains error details, upload response and uploadId that was assigned to current file.
- `options`: object that contains the upload response and uploadId

example

```js
scaleflexWidget.on("upload-error", (file, error, { response, uploadId }) => {
  console.log(
    "File faced that error while uploading",
    file,
    error,
    response,
    uploadId
  );
});
```

**upload-retry** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on some file uploading is retried.

`params`:

- `fileId`: The id of the file which its upload process is retried.

example

```js
scaleflexWidget.on("upload-retry", (fileId) => {
  console.log("The following file id is being re-uploaded:", fileId);
});
```

**progress** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on having a progress of an upload process's total progress.

`params`:

- `totalProgress`: The total progress value of the current uploading process.

example

```js
scaleflexWidget.on("progress", (totalProgress) => {
  console.log("The uploading total progress for now: ", totalProgress);
});
```

**cancel-uploads** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when the whole upload process is canceled (all files uploading are canceled).

`params`: No params returned.

example

```js
scaleflexWidget.on("cancel-uploads", () => {
  console.log("The upload is canceled");
});
```

**complete** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when the whole upload process done and completed.

`params`:

- `completionObject`: An object contains the results of the completed upload process, ex. `{ failed: failedFiles, uploadId: ..., successful: uploadedFiles }`.

example

```js
scaleflexWidget.on("complete", ({ failed, uploadId, successful }) => {
  console.log(
    `The upload ${uploadId} is completed with following results success then failed files`,
    successful,
    failed
  );
});
```

**items-deleted** ![asset-manager-supported]  

Emitted when files/folders are deleted.

`params`:

- `detailsObject`: An object contains details of removed items, ex. `{ removedFolders: [...], removedFiles: [...] }`.

example

```js
scaleflexWidget.on("items-deleted", ({ removedFolders, removedFiles }) => {
  console.log("Items deleted:");
  console.log("Removed folders:", removedFolders);
  console.log("Removed files:", removedFiles);
});
```

**error** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when the whole upload process faced an error.

`params`:

- `filesIds`: files ids that have an error.
- `error`: The error shown of the uploading process.
- `uploadId`: The id of the errored uploading process.

example

```js
scaleflexWidget.on("error", (filesIds, error, { uploadId }) => {
  console.log(
    `The upload with id ${uploadId} faced this error while uploading`,
    error
  );
});
```

**reset-progress** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted when the upload's progress is reset to 0.

`params`: No params returned.

example

```js
scaleflexWidget.on("reset-progress", () => {
  console.log("The progress is reset");
});
```

**info-visible** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on showing an `info` message to the user.

`params`: No params returned.

example

```js
scaleflexWidget.on("info-visible", () => {
  console.log("inFo message shown.");
});
```

**info-hidden** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on hiding an `info` message that were shown to the user.

`params`: No params returned.

example

```js
scaleflexWidget.on("info-hidden", () => {
  console.log("The progress is hidden.");
});
```

**explorer:modal-open** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on opening the widget in a modal through the [**Explorer**](https://www.npmjs.com/package/@scaleflex/widget-explorer) plugin.

`params`: No params returned.

example

```js
scaleflexWidget.on("explorer:modal-open", () => {
  console.log("The widget's explorer modal is opened .");
});
```

**explorer:modal-close** ![uploader-supported] ![asset-picker-supported] ![asset-manager-supported]  

Emitted on closing the widget's main modal.

`params`: No params returned.

example

```js
scaleflexWidget.on("explorer:modal-close", () => {
  console.log("The widget's modal is closed.");
});
```

**export** ![asset-picker-supported] ![asset-manager-supported]  

emitted when the user downloads a file.

`params`:

- `files`: An array of files checked/selected for exporting.
- `popupExportSucessMsgFn`: A function if called will show exported successfully pop-up to the user.
- `downloadFilesPackagedFn`: A function if called will download files (the files passed in the first argument if nothing passed then the files exported will be used) as ZIP and show download progress in widget (item's Uuid is used & must exists on backend's side -- NOT FULLY WORKING --).
- `downloadFileFn`: A function if called will download one file (the file passed as first argument if nothing passed then the first file in exported files will be used) directly without packaging/zipping it and show download progress in widget (`file.url.download` link is used in download and fallbacks to `file.url.permalink`).

example

```js
scaleflexWidget.on(
  "export",
  (files, popupExportSucessMsgFn, downloadFilesPackagedFn, downloadFileFn) => {
    console.log("The following files are chosen to be exported", files);
    popupExportSucessMsgFn(); // shows exported successfully message as pop-up.
    downloadFilesPackagedFn(files.slice(1).map(({ file }) => file)); // no need to pass file.slice(1) if u would download all exported files.
    const { file } = file[0];
    downloadFileFn({ ...file, url: { ...file.url, download: files[0].link } }); // no need to pass file[0] if u would download the first file of exported files.
  }
);
```

**url-modified** ![asset-manager-supported]  

Emitted when the user uses the [**Image Editor**](https://www.npmjs.com/package/@scaleflex/widget-image-editor) in Cloudimage mode and changes the url.

`params`:

- `modifiedUrl`: The modified url for the image.
- `designState`: The image editor's design state object.
- `info`: the function that gives you possibility to show a `@scaleflex/widget-informer` message.

example

```js
scaleflexWidget.on('modified-url', (modifiedUrl, designState, info) => {
  console.log('The new url is', modifiedUrl)
  console.log('Image editor design state:', designState)
  info('Url has changed', 'success', 3000)
})

```

### Plugin APIs (advanced use)

Utilize the widget’s instance APIs to apply different functionalities on the current instance programmatically with the reflection on the UI.

**scaleflexWidget.getId()**

Gets the Scaleflex Media Asset Widget's current instance id.

**scaleflexWidget.use(plugin, pluginOptions)**

Adds a plugin to the Scaleflex Media Asset Widget's instance.

```js
// example
import ScaleflexWidget from '@scaleflex/widget-core'
import Explorer from '@scaleflex/widget-explorer'

const scaleflexWidget = ScaleflexWidget()
scaleflexWidget.use(Explorer, {...})
```

**scaleflexWidget.getPlugin(pluginId)**

Returns the plugin's instance with the provided id for accessing its methods & state.

**scaleflexWidget.removePlugin(pluginInstance)**

Removes a currently initialized plugin by passing the plugin's instance retrieved from the [getPlugin](https://www.npmjs.com/package/@scaleflex/widget-core#scaleflexwidgetgetpluginpluginid) method.

**scaleflexWidget.setOptions(options)**

Passes [Properties](https://www.npmjs.com/package/@scaleflex/widget-core#parameters) to the Widget to change properties set during initialization:

```js
import ScaleflexWidget from "@scaleflex/widget-core";

const scaleflexWidget = ScaleflexWidget();
scaleflexWidget.setOptions({
  autoProceed: true,
});
```

Individual plugin options can also be changed by using [getPlugin](https://www.npmjs.com/package/@scaleflex/widget-core#scaleflexwidgetgetpluginpluginid)

```js
import Scaleflex from "@scaleflex/widget-core";

const scaleflexWidget = ScaleflexWidget();
scaleflexWidget.use(Explorer, { id: "Explorer" });
scaleflexWidget.getPlugin("Explorer").setOptions({
  animateOpenClose: false,
});
```

**scaleflexWidget.addFile(fileObject)**

Adds a file into the widget's state and returns the temporary generated id for that file.

> [restrictions](https://www.npmjs.com/package/@scaleflex/widget-core#restrictions) are checked and [onBeforeFileAdded](https://www.npmjs.com/package/@scaleflex/widget-core#onbeforefileadded) called before adding the file.

**scaleflexWidget.getFile(fileId)**

Gets the file object using its id.

**scaleflexWidget.removeFile(fileId)**

Removes a file from the widget's state via its id.

**scaleflexWidget.getFiles()**

Returns all the file objects currently loaded in the widget.

**scaleflexWidget.upload(files, callback)**

An async function that starts uploading files, returns a promise resolved with an object `result: { successful, failed }` containing:

- `successful`: array with file objects successfully uploaded.
- `failed`: array with files objects for which upload failed.

**scaleflexWidget.retryUpload(fileId)**

Retries a failed upload for a file referenced by its id.

**scaleflexWidget.cancelUploads()**

emit [cancel-uploads](https://www.npmjs.com/package/@scaleflex/widget-core#cancel-uploads) event and cancel uploads.

**scaleflexWidget.setCoreCommonState(object)**

Updates the internal state of the widget's core common state.

**scaleflexWidget.getGlobalState()**

Returns the internal state/store of the widget's.

updates the state of a file inside the uploads panel before triggering upload.

**scaleflexWidget.setFileUploadingState(fileId, state)**

updates the state of a file uploading.

**scaleflexWidget.getFileUploading(fileId)**

Returns a file that is uploading.

**scaleflexWidget.setFilesInfoMetaTags(fileIds, filesInfoMetaTagsData, forceUpdate)**

Updates the info and/or meta object(s) of the passed files that would be uploaded with the provided `info` and `meta` objects parameters received from `filesInfoMetaTagsData` object in the following format `{ info: {}, meta: {}, tags: {} }`, `forceUpdate` means replace the current tags instead of deep merging with the current ones.

**scaleflexWidget.close()**

Removes all the installed plugins & closes the current widget's instance.

**scaleflexWidget.on('event', handler)**

Adds/Subscribe a handler/callback function to be called on emitting/firing the specified `scaleflexWidget event`, [full list of available events](https://www.npmjs.com/package/@scaleflex/widget-core#events).

**scaleflexWidget.once('event', handler)**

Same as `scaleflexWidget.on` but the handler is removed after being called once.

**scaleflexWidget.off('event', handler)**

Un-subscribe/Removes the specified handler for scaleflexWidget's event.

**scaleflexWidget.info(message, type, timeout)**

Shows an informer with the specified message to the user:

| Property  | Type                            | Default     | Description                                                                                                                                                                                    |
| --------- | ------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message` | `string` \| `object` *Required* | `undefined` | Defines the message to be shown to the user, either a string ex. `Some message` or `{ message: 'Some headline message', details: 'Detailed message would be shown on hovering the informer' }` |
| `type`    | `string`                        | `info`      | choses the type of the informer whether `info, warning or success`                                                                                                                             |
| `timeout` | `number`                        | `3000`      | The duration which the message would still be shown for in milliseconds                                                                                                                        |

**scaleflexWidget.log(message, type)**

Logs a message in the `logger`:

| Property  | Type                | Default     | Description                                                            |
| --------- | ------------------- | ----------- | ---------------------------------------------------------------------- |
| `message` | `string` *Required* | `undefined` | the message would be logged/added/shown in the logger.                 |
| `type`    | `string`            | `debug`     | the type of that logged message whether `debug/info, warning or error` |

<!-- Variables -->

[npm-url]: https://www.npmjs.com/package/@scaleflex/widget-core
[license-url]: https://opensource.org/licenses/MIT
[sfx-url]: https://www.scaleflex.com/
[version-url-latest]: https://www.npmjs.com/package/@scaleflex/widget-core
[version-url-stable]: https://www.npmjs.com/package/@scaleflex/widget-core/v/stable
[version-url]: https://www.npmjs.com/package/@scaleflex/widget-core
[codeSandbox-url]: https://codesandbox.io/p/sandbox/r9scjl
[npm-image]: https://img.shields.io/npm/v/@telus/remark-config.svg?style=for-the-badge&logo=npm
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge
[made-by-image]: https://img.shields.io/badge/%3C%2F%3E%20with%20%E2%99%A5%20by-the%20Scaleflex%20team-6986fa.svg?style=for-the-badge
[plugins-image]: https://img.shields.io/static/v1?label=Scaleflex&message=Plugins&color=yellow&style=for-the-badge
[filerobot-image]: https://img.shields.io/static/v1?label=Scaleflex&message=website&color=orange&style=for-the-badge
[filerobot-version-latest]: https://img.shields.io/npm/v/@scaleflex/widget-core?label=latest&style=for-the-badge&logo=npm
[filerobot-version-stable]: https://img.shields.io/npm/v/@scaleflex/widget-core/stable?label=stable&style=for-the-badge&logo=npm
[filerobot-version]: https://img.shields.io/npm/v/@scaleflex/widget-core?label=Version&style=for-the-badge&logo=npm
[codeSandbox-image]: https://img.shields.io/badge/CodeSandbox-black?style=for-the-badge&logo=CodeSandbox
<!-- Supported modes variables -->
[uploader-supported]: https://img.shields.io/badge/Uploader-orange
[asset-picker-supported]: https://img.shields.io/badge/Asset%20Picker-green
[asset-manager-supported]: https://img.shields.io/badge/Asset%20Manager-blue
<!-- Usage -->
<!-- ![uploader-supported]
![asset-picker-supported]
![asset-manager-supported] -->

## License

The Scaleflex Media Asset Widget (SMAW) is provided under the [MIT License](https://opensource.org/licenses/MIT)