{"id":18300336,"url":"https://github.com/jpdevries/eureka","last_synced_at":"2025-07-28T23:32:20.024Z","repository":{"id":29482794,"uuid":"33019944","full_name":"jpdevries/eureka","owner":"jpdevries","description":"HTML-first crack at a Flexible Media Browser progressively enhanced with React","archived":false,"fork":false,"pushed_at":"2017-08-14T21:13:41.000Z","size":28850,"stargazers_count":18,"open_issues_count":41,"forks_count":5,"subscribers_count":4,"default_branch":"release-2.0","last_synced_at":"2024-04-30T06:21:11.862Z","etag":null,"topics":["accessibility","browse","contrast-theme","html","media","modmore","modx","nodejs","progressive-enhancement","progressive-web-app","react","redux","rest"],"latest_commit_sha":null,"homepage":"https://eureka.markup.tips/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jpdevries.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-28T03:42:05.000Z","updated_at":"2020-05-03T18:58:14.000Z","dependencies_parsed_at":"2022-08-31T00:01:31.587Z","dependency_job_id":null,"html_url":"https://github.com/jpdevries/eureka","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Feureka","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Feureka/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Feureka/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpdevries%2Feureka/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpdevries","download_url":"https://codeload.github.com/jpdevries/eureka/tar.gz/refs/heads/release-2.0","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227962261,"owners_count":17847912,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","browse","contrast-theme","html","media","modmore","modx","nodejs","progressive-enhancement","progressive-web-app","react","redux","rest"],"created_at":"2024-11-05T15:12:04.147Z","updated_at":"2024-12-03T17:15:21.152Z","avatar_url":"https://github.com/jpdevries.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Eureka 🌲\n[![Build Status](https://travis-ci.org/jpdevries/eureka.svg?branch=release-2.0)](https://travis-ci.org/jpdevries/eureka) [![npm version](https://badge.fury.io/js/eureka-browser.svg)](https://badge.fury.io/js/eureka-browser)\n\nEureka is a progressively enhanced flexible media browser. Connected to your media sources through a REST API, this accessible web component allows users to browse media sources, upload files, and choose media items.\n\n[🤗 Try the demo](https://eureka.markup.tips/). \n\n\u003e With `eureka.js` users will be saying \"I found it!\" in no time.\n\u0026emsp;\u0026emsp;\u0026mdash; [@mrktps](https://twitter.com/mrktps)\n\n## 💬 Discuss\nJoin the conversation in our public Gitter chat room.\n\n[![Join the chat at https://gitter.im/jpdevries/eureka](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jpdevries/eureka?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n## 📚 Wiki\nDon't forget to [browse the Wiki](https://github.com/jpdevries/eureka/wiki) for [more information on the REST API](https://github.com/jpdevries/eureka/wiki/REST-API), [patterns](https://github.com/jpdevries/eureka/wiki/Patterns), [screenshots](https://github.com/jpdevries/eureka/wiki/Screenshots) and\u0026nbsp;more.\n\n## 🍻 Support\nThe Eureka Media Browser and supporting resources are provided free as in\u0026nbsp;beer.  \n[Gratuities are accepted through Square\u0026nbsp;Cash](https://cash.me/$devriesdev).\n\n## 🏋️‍♀️ Weigh In\nThe Eureka Media Browser is pretty lightweight all things\u0026nbsp;considered.\n\n| Asset        | Weight (GZIP minified)\n| ------------- |:-------------:|\n| CSS Stylesheet      | `7.83kB` |\n| SVG Icons      | `7.88kB`      |\n| React Component | `75.83kB`    |\n\n[Have a gander at our Webpack Visualizer](https://eureka.markup.tips/assets/js/stats.html)\u0026nbsp;👀 .\n\n### 📄 HTML\u0026ndash;first\nAs a progressively enhanced web component, Eureka is functional HTML\u0026ndash;first. This means that technically anything other than the initial HTML layer is a non\u0026ndash;critical enhancement. Critical features supported by the HTML layer, such as browse, upload, and choose, are universally supported and do not depend on modern\u0026nbsp;browsers, CSS styles, or\u0026nbsp;script.\n\n😲 Take a gander at Eureka in the nued by waking our incredibly lightweight [raw HTML\u0026nbsp;example](https://reacteureka.herokuapp.com/nued).\n\nWe also encourage you to temporarily disable JavaScript in your browser and party with Eureka like it's\u0026nbsp;1999.\n\n## Powered By 🚀\n - Progressively Enhanced from HTML components\n - All\u0026ndash;new Virtual DOM powered by React/Redux\n - Node Server Side Rendering\n - Node testing server\n\n## Highlights 🖋\n - Configurable Rest API endpoints\n - Browse multiple media sources for images\n - Drag and Drop Upload Support\n - Flexible Layout\n - Responsive Design\n - Save Data with responsive thumbnails\n - Configurable Styles via CSS Variables\n - Accessible\n   - supports mobile and touch devices\n   - supports `.no-js` via server side rendering\n   - ARIA \u0026 Keyboard Support\n   - high contrast themes\n\n## 🚥 Features\nThe level of isomorphism between the client and server side one can achieve with Node is unmatched. Eureka takes advantage of this unique strength of Node by, through an isomorphic server and standard synchronous forms, achieving full support for critical\u0026nbsp;features.\n\nNo features rely solely on sight or the use of a mouse. Keyboard use is supported. Accommodations are taken for users that benefit from high contrast themes. Visually hidden text is used to convey aspects of the interface that are otherwise visually implied to screen readers and assistive\u0026nbsp;technology.\n\nThe semantic HTML layer remains usable even absent of style as pure\u0026nbsp;HTML.\n\n\u003ctable\u003e\n  \u003ccaption style=\"text-align:center\"\u003eSupport of features against browser environments\u003c/caption\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eFeature\u003c/th\u003e\n      \u003cth\u003e\u003ccode\u003e.no-js\u003c/code\u003e\u003c/th\u003e\n      \u003cth\u003e\u003ccode\u003e\u003c IE 9\u003c/code\u003e\u003c/th\u003e\n      \u003cth\u003eChrome\u003c/th\u003e\n      \u003cth\u003eSafari\u003c/th\u003e\n      \u003cth\u003eFirefox\u003c/th\u003e\n      \u003cth\u003eIE 11\u003c/th\u003e\n      \u003cth\u003eEdge\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eUpload multiple files\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eBrowse directories\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eChoose a media item\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n        \u003ctr\u003e\n      \u003ctd\u003eKeyboard Support\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eARIA Support\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"partial supported\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eWCAG Level AA\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eInternationalization\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eDownload Item\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eChoose Multiple Items\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eDelete Multiple Items\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eKeyboard Shortcuts\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eCrop Images\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003ePaste to Upload\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eMedia Source panel\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eAsync UX\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFilterable Data Table\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eSortable Data Table\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eDrag 'n drop uploads\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eGrid Layout\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFlexible Layout\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eView Chooser\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eMasonry Layout Mode\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003ePathbar\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eRename Item\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eDelete Item\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eDownload Multiple Items\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eLocal Storage\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eVariable Styles\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eAccessible Themes\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eMobile First Layout\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"partial supported\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eFullscreen Mode\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eHTML5 Context Menus\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"can be enabled\"\u003e🔧\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eHTML5 Details\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported via polyfills\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"partial supported\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eHTML5 Datalist\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported via polyfills\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"not supported\"\u003e❌\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported\"\u003e✅\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"partial supported\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003cspan aria-label=\"supported via polyfills\"\u003e✳️\u003c/span\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n## 🛠 Usage\n\n```bash\nnpm install eureka-browser --save\n```\n\n#### Bower\nYou can also install Eureka via Bower, which is a good way to fetch its stylesheet and icon sprite. There is also a UMD export of the `EurekaMediaBrowser` component for the unlikely case you'll need\u0026nbsp;it.\n\n```bash\nnpm install -g bower\n```\n\n```bash\nbower install eureka-browser#release-2.0\nls bower_components/eureka-browser/client/build/assets/css/ # default eureka theme\nls bower_components/eureka-browser/client/build/assets/img # icon sprite\nls bower_components/eureka-browser/client/build/assets/js # bundled and unbundled UMD exports of EurekaMediaBrowser component\n```\n\n#### HTML\nThe `\u003cEurekaMediaBrowser\u003e` React component is styled by a standard CSS stylesheet. Include the CSS for the appropriate version of the media browser. Reference the theming section for [more information on styling Eureka](https://github.com/jpdevries/eureka#-theming).\n\n```html\n\u003clink rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"bower_components/eureka-browser/client/build/assets/css/eureka.0.0.20.min.css\"\u003e\n```\n\n```html\n\u003cdiv id=\"eureka-root\"\u003e\n  \u003c!-- for performance, optimization, and accessibility it best to support server-side rendering by initially delivering a base HTML layer\n  see server-side rendering below --\u003e\n\u003c/div\u003e\n\n```\n\n#### JS\n```js\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { EurekaMediaBrowser } from 'eureka-browser';\n\nReactDOM.render(\n  \u003cEurekaMediaBrowser /\u003e,\n  document.getElementById('eureka-root')\n);\n```\n\nEureka will then be injected into the DOM and eagerly reach out to the REST API for the JSON data it needs to offer the\u0026nbsp;interface.\n\nConfigure the `EurekaMediaBrowser` via the optional attributes found in the default configuration\u0026nbsp;below:\n```xml\n  \u003cEurekaMediaBrowser\n    basePath=\"/\"\n    allowUploads={true}\n    treeHidden={true}\n    useLocalStorage={true}\n    storagePrefix=\"eureka__\"\n    allowRename={true}\n    allowDelete={true}\n    confirmBeforeDelete={false}\n    locale=\"en-US\"\n    mediaSource=\"0\"\n    currentDirectory=\"/\"\n    headers={{\n        'Powered-By': 'Eureka by Markup.tips'\n    }}\n    intervals={{\n      searchBarPlaceholder: false,\n      fetchDirectoryContents: 18000,\n      updateSourceTree: false\n    }}\n  /\u003e\n```\n\n## ⚙️ Options\n\n| Option        | Default           | Description  |\n| ------------- |:-------------:| -----|\n| `basePath`      | `\"/\"` | Prepended to URLs for XHR requests to the Rest API.\u003cbr\u003eSet to the absolute path of your Rest API. |\n| `allowUploads`      | `true`      |   Whether or not to allow uploading of media items |\n| `treeHidden` | `true`      |    Whether or not the Media Source Panel \"sidebar\" should be initially closed |\n| `useLocalStorage` | `true`      |    Whether or not to use the JavaScript `localStorage` API to remember session data such as the last visited directory and view mode preference |\n| `storagePrefix` | `\"eureka__\"`      |    Prepended to `localStorage` keys |\n| `allowRename` | `true`      |    Whether or not to offer users the ability to rename directories and media items |\n| `allowDelete` | `true`      |    Whether or not to offer users the ability to delete directories and media items |\n| `allowDownload` | `false`      |    Whether or not to add a download button to media items |\n| `confirmBeforeDelete` | `false`      |    Whether or not to confirm intent before users delete directories and media items |\n| `locale` | `\"en-US\"`      |    The localization to use. See Lexicons. |\n| `mediaSource` | `undefined`      |    The default initial media source id to use |\n| `currentDirectory` | `\"/\"`      |    The default initial directory to use |\n| `uid` | `\"0\"`      |    A unique identifier used to ensure multiple `\u003cEurekaMediaBrowser\u003e` components on the same page do not share the same DOM ids  |\n| `assetsBasePath` | `\"./assets/\"`      |    Relative path to the Eureka assets directory |\n| `iconSVG` | `\"./img/icons.svg\"`      |    Path, relative to `assetsBasePath`, to the Eureka icon sprite sheet |\n| `callbacks` | `{close: undefined, choose: undefined}`      |    Object containing close and choose callbacks |\n| `headers` | `{'Powered-By': 'Eureka by Markup.tips'}`      |    Additional request headers sent with XHR requests |\n| `intervals` | `{searchBarPlaceholder: false,fetchDirectoryContents: 18000,updateSourceTree: false}`      |    Intervals for whether or not and how often to do things like hit the REST API for updated data or update the placeholder attribute based on the current directory listing  |\n| `enlargeFocusedRows` | `false`      |    Whether or not to enlarge thumbnails of focused rows |\n| `mode` | `\"table\"`      |    Initial view mode (table, thumb, grid, list) |\n| `sort` | `\"name\"`      |    Initial column to sort media items on |\n| `allowFullscreen` | `true`      |    Whether or not the interface should offer a fullscreen button |\n| `emphasisFocusedMediaItem` | `true`      |    Whether or not to emphasis selected media items (defaults to emphasizing the filename, only applies to table and list view modes) |\n| `doDragNDrop` | `true`      |    Whether or not to enable drag 'n drop features |\n| `allowChooseMultiple` | `true`      |    Whether or not to allow multiple files to be chosen |\n| `allowInvertSelection` | `true`      |    Whether or not to allow selection of multiple items to be inverted |\n| `allowDownloadMultiple` | `true`      |    Whether or not to allow multiple selected items to be download as a zip file |\n\n\n\n*Please take note that when `useLocalStorage` is `true` any options manually passed in as props will take\u0026nbsp;precedent.*\n\n## 🌐 Browser Support\nThe server side rendering and HTML\u0026ndash;first design patterns begin progressively enhancing a universally supported HTML layer. So basic features are supported in any browser. JavaScript support begins at IE9. Desired CSS layout requires Flexbox and is further enhanced with Grid Layout.\n\n## 🔡 i18n\nEureka is on Crowdin. Please [contribute to our translations](https://crowdin.com/project/eureka-browser) if you are\u0026nbsp;able.\n\n## ♿️ Accessibility Proclaimer\nEureka strives for WCAG Level AA success criteria in all scenarios with some accessibility preference features leaning towards Level AAA. Please [log *any* a11y issues here](https://github.com/jpdevries/eureka/issues).\n\n## ✅ Getting Started\nWe're going to use `yarn` so make sure that is installed.\n\n```bash\nnpm install yarn -g\n```\n\nTo fire up a testing server run the following:\n\n```bash\ngit clone -b release-2.0 git://github.com/jpdevries/eureka.git\ncd eureka\nyarn prestart\nyarn build\nyarn serve # start the  development server\n# open http://localhost:3001 # Node server\n```\n\nTo host the compiled production server run\n```bash\nyarn start # install, fetch sources, build\n```\n\nor\n```bash\nyarn prod # fire up the production server\n```\n\nThe testing server hosts the `sources` and `client/build` directories along with a REST API to `GET`, `POST`, `PUT`, `DELETE` media items.\n\n![](http://j4p.us/22241J1A3N06/Screen%20Shot%202017-03-13%20at%2012.56.51%20AM.png)\n\n## ⚒ Development\nThe Eureka component is created with `create-react-app` and found in the `client` directory. There you can run React tests, build the React component, and start the development server.\n\nFirstly, you'll need the testing server running for the REST API:\n```bash\ncd eureka\nyarn server\n```\n\nNow, in another terminal tab:\n\n```bash\ncd client\nyarn build\nyarn test\nyarn start\n# open http://localhost:3000 # development server\n```\n\nThe development server, like any other React app created with `create-react-app`, will automatically inject changes as you save changes to your source files.\n\n## 🗄 REST API\nEureka is hungry for remote media sources. It needs a REST API to feed it JSON\u0026nbsp;data.  \nFind docs at the [REST API wiki page](https://github.com/jpdevries/eureka/wiki/REST-API).\n\n### 💄 Decorating Actions\nEureka's core Redux actions assume you'll be using a REST API. If REST isn't really your thing, or you need to modify the Redux actions for some other reason, you can decorate the actions Eureka will use. This is done using a Higher Order Component that wraps `EurekaMediaBrowser` and injects a `decoratedActions` property which will be applied as a shallow merge on top of the default\u0026nbsp;actions. Reference this [Gist example of decorating actions](https://gist.github.com/jpdevries/e967056bd31cf6f01df0e431df68283b) for an example.\n\n## 📠 Server Side Rendering\nEureka is progressively enhanced with React to be asynchronous and a richer experience in capable browsers that successfully execute scripts. But Eureka's support doesn't end at modern browsers because its design process doesn't start there. Eureka is a semantic and synchronous HTML form before it is an enhanced Virtual\u0026nbsp;DOM.  \n\nReference the [Server Side Rendering Wiki page](https://github.com/jpdevries/eureka/wiki/Server-Side-Rendering) for documentations and examples on achieving world wide\u0026nbsp;support.\n\n### ⌨️ Keyboard Shortcuts\nEureka uses JavaScript events to enrich the user experience of keyboard\u0026nbsp;users.\n\n| Shortcut        | Command              |\n| --------------- |:-------------:       |\n| Toggle Sidebar      | ctrl+;           |\n| Change View      | ctrl+alt+(1-5)      |\n| Change Media Source | alt+(1-9)        |\n| Delete Item | backspace                |\n| Expand Item | spacebar                 |\n| Choose Item | return                   |\n| Create Directory | ctrl+n              |\n| Create file | ctrl+shift+n              |\n| Upload Files | ctrl+u                  |\n| Rename Item | ctrl+r                   |\n| Filter Items | ctrl+f                  |\n| Sort Ascending | alt+up                  |\n| Sort Descending | alt+down                  |\n| Sort by filename | alt+n                  |\n| Sort by dimensions | alt+d                  |\n| Sort by file size | alt+f                  |\n| Sort by edited on | alt+e                  |\n| Set Choose Mode to Single | alt+s                  |\n| Set Choose Mode to Multiple | alt+m                  |\n| Invert Selection | alt+i                  |\n\n\n## 🎨 Theming\nRequest additional theming options and share your themes by [opening an issue](https://github.com/jpdevries/eureka/issues/new) or [joining the discussion on\u0026nbsp;Gitter](https://gitter.im/jpdevries/eureka?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge).\n\n| Variable        | Description  |\n| ------------- | -----|\n| `--active` | Color used to highlight activated components such as the drop area |\n| `--border-width` | Generic border width for panels, components, inputs |\n| `--border-style` | Generic border style for panels, components, inputs |\n| `--border-color` | Generic border color for panels, components, inputs |\n| `--button-bg` | Background color of button elements |\n| `--button-color` | Color of button text |\n| `--color` | Default text color |\n| `--dangerous` | Color to use for warnings and errors |\n| `--light-bg` | Generic light background color, used for panels |\n| `--link-color` | Default anchor text color |\n| `--panel-border-color` | Border color of panel components |\n| `--subtle` | Subtle color, used for Media Source Panel |\n| `--very-subtle` | Very subtle color, used for drop zone area |\n| `--very-subtle-icon-opacity` | Opacity for very subtle icons |\n\n## 📣 Audible Interface\nEureka uses a combination of ARIA attributes and `.visually-hidden` text to offer an experience that is as accessible visually as it is\u0026nbsp;audibly.\n\n![The Eureka Browser interface without as seen by a screen reader includes  descriptive text for an accessible experience](http://j4p.us/3h1e2G0B0b0q/Screen%20Shot%202017-04-25%20at%205.25.24%20PM.png)\n\nThere is one Achilles heel here. Depending on your media source API, you might not be able to provide alternative text for images and media items. In the event that no alt text is provided, Eureka will to the best it can. For example:\n\n\u003e schildpad.jpg displays at 336x125, weighs 37 KB, and was edited on Sunday, April 02, 2017, Central European Summer Time\n\n## 📺 Fullscreen Mode\nTo maximize usability Eureka leverages the Fullscreen\u0026nbsp;API.\n\n\u003cdetails\u003e\n\u003csummary\u003eSee the Fullscreen Mode in action\u003c/summary\u003e\n\u003cimg src=\"http://j4p.us/1h2w3E1d2h2a/fs.gif\"\u003e\n\u003c/details\u003e\n\n## 🏞 Masonry Layout\nEureka is enhanced by a Masonry Layout mode.\n\n\u003cdetails open\u003e\n\u003csummary\u003eMasonry Layout Mode\u003c/summary\u003e\n\u003cimg src=\"http://j4p.us/1S1h282v2J0N/Screen%20Shot%202017-04-30%20at%208.51.21%20PM.png\" /\u003e\n\u003c/details\u003e\u003cbr\u003e\n\nIf you are using Eureka as a UMD Module (probably not) you'll need [to load Masonry first](https://github.com/jpdevries/eureka/wiki/Loading-Patterns-(WIP)). If you would not like Masonry to be included in your bundle, add Masonry to your Webpack excludes. Eureka will only enable the Masonry Layout if Masonry is available.\n\n```js\nexternals: {\n  \"react\": \"React\",\n  \"react-dom\":\"ReactDOM\",\n  \"redux\":\"Redux\",\n  \"react-redux\":\"ReactRedux\",\n  \"react-masonry-component\":\"Masonry\"\n}\n```\n\n\n## 👀 Accessible Themes\nEureka is empowered by themes which make it more accessible to users with particular physical or contextual disabilities or preferences.\n\n### Black on White\n![](http://j4p.us/091n1d1z3y1F/Screen%20Shot%202017-03-16%20at%203.33.14%20AM.png)\n\n### White on Black\n![](http://j4p.us/3O163v400P30/Screen%20Shot%202017-03-16%20at%203.33.45%20AM.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpdevries%2Feureka","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpdevries%2Feureka","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpdevries%2Feureka/lists"}