Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Ars Arsenal


A gallery picker. ArsArsenal makes it easy to quickly select photos and other resources for content management purposes. Additionally, it supports features such as:

  • Table/Gallery view
  • Pagination
  • Sorting
  • Search

Heads up! we recently made some breaking changes to configuration in version 3.0.0. See the CHANGELOG for more information.



npm install --save ars-arsenal
# or use yarn
yarn add ars-arsenal


Ars Arsenal ships with a stylesheet. The easiest way to include it is by importing it from the node_modules folder:

/* Sass stylesheet: */
@import './node_modules/ars-arsenal/style/ars-arsenal.scss'; /* or CSS: */
@import './node_modules/ars-arsenal/style.css';


ArsArsenal can be rendered either as a stand-alone instance or as a React component:

Stand Alone

import ArsArsenal from 'ars-arsenal'

let app = document.getElementById('app')

ArsArsenal.render(app, {
  autoComplete: true, // Show or hide autocomplete results

  resource: 'photo', // the noun used for selection, i.e. "Pick a photo"

  // Configure the root element's HTML attributes. default = {}
  rootAttributes: {
    className: 'my-custom-class another-custom-class',
    'data-test': 'my-integration-selector-helper'

  // The base URL for API interaction
  url: 'photo/resource/endpoint',

  // How to display the items. Can be "table" or "gallery"
  mode: 'gallery',

  // What table columns to display, and in what order
  columns: ['id', 'name', 'caption', 'attribution', 'preview'],

  multiselect: false,

  listUrl: function(url) {
    // Used to build the URL that fetches lists of records.
    return url

  listQuery: function({ search, page, sort }) {
    // Use this function to rename query parameters before building
    // the listUrl URL
    // Any data returned from this function will be stringified into
    // query parameters
    return { search, page, sort }

  showUrl: function(url, id: ID) {
    // Used to build the URL that fetches a single record
    return `${url}/${id}`

  onError: function(response) {
    // format errors before they are sent as a "string" value
    // to the component
    return response.code + ': ' + response.message

  onFetch: function(response) {
    // format the response, useful if you do not control the JSON
    // response from your endpoint

  onChange: function(id) {
    // Whenever a new item is picked, this event is triggered
    console.log('The value was changed to %s', id)

  request: function(url, callback) {
    // Behavior to configure networking. Return an XMLHTTPRequest
    return xhr(url, callback)

  logger: function(level, message) {
    // Override this method to handle usage warnings and issues
    // ArsArsenal considers errors with API interaction. Useful
    // for monitoring.
    switch (level) {
      case 'warning':
      case 'error':


import React from 'react'
import ReactDOM from 'react-dom'
import { Ars } from 'ars-arsenal'

let app = document.getElementById('app')

let options = {
  /* same options as above */

ReactDOM.render(<Ars options={options} />, app)

Response format

APIs return different shapes of data. To account for this, ArsArsenal exposes the onFetch option. This option is called whenever data is fetched from your API:

let options = {
  onFetch: function(response) {
    // format the response, useful if you do not control the JSON
    // response from your endpoint

ArsArsenal expects the following data format:

    "id": 1,
    "attribution": "League of Legends",
    "name": "Alistar",
    "caption": "Lorem ipsum dolor sit amet",
    "url": "images/alistar.jpg",
    "tags": ["blue", "cunning"]

To transpose data, map over it in onFetch like so:

let options = {
  onFetch: function(response) {
    return {
      return {
        name: record.title,
        caption: record.caption,
        url: record.imageSrc,
        tags: record.tags


To enable sorting, take advantage of the sort field passed into the listQuery option. listQuery will automatically stringify the returned object:

function listQuery({ page, search, sort }) {
  // Assuming your API requires a call like:
  // /photos?page=1&q=Dogs&sortKey=breed
  return {
    page: page,
    q: search,
    sortKey: sort


Take a look at our contributing guide, but the gist of it is:

# Install dependencies
yarn install
# Spin up the example server with:
yarn start

Code At Viget

Visit to see more projects from Viget.