Prototyped icon search

This commit is contained in:
squidfunk 2021-02-06 12:35:19 +01:00
parent 08340e42a1
commit 0116f636f2
36 changed files with 330 additions and 54 deletions

View File

@ -25,3 +25,6 @@ src/**/*.html
# Don't lint shame
src/assets/stylesheets/_shame.scss
# Prevent stylelint from constantly complaining
webpack.config.ts

View File

@ -5,10 +5,22 @@ template: overrides/main.html
# Icons + Emojis
One of the best features of Material for MkDocs is the possibility to use [more
than 7.000 icons][1] and thousands of emojis in your project documentation
than 8.000 icons][1] and thousands of emojis in your project documentation
with practically zero additional effort. Furthermore, custom icons can be added
and used in `mkdocs.yml`, documents and templates.
## Search
<input id="icon-search" class="md-input" placeholder="Search the icon database" />
<div class="tx-icon-result" markdown="1">
<small>
:octicons-light-bulb-16:
**Tip:** Enter some keywords to find the perfect icon and click on the
shortcode to copy it to your clipboard.
</small>
</div>
## Configuration
### Emoji

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,16 +1,16 @@
{
"assets/javascripts/bundle.js": "assets/javascripts/bundle.87ed5edf.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.87ed5edf.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.d018e87b.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.d018e87b.min.js.map",
"assets/javascripts/bundle.js": "assets/javascripts/bundle.d3f6ab33.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.d3f6ab33.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.f03b12a7.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.f03b12a7.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.9c0e82ba.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.9c0e82ba.min.js.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.0258fc15.min.css",
"assets/stylesheets/main.css.map": "assets/stylesheets/main.0258fc15.min.css.map",
"assets/stylesheets/palette.css": "assets/stylesheets/palette.5b7c1fa0.min.css",
"assets/stylesheets/palette.css.map": "assets/stylesheets/palette.5b7c1fa0.min.css.map",
"overrides/assets/javascripts/bundle.js": "overrides/assets/javascripts/bundle.cdb09f69.min.js",
"overrides/assets/javascripts/bundle.js.map": "overrides/assets/javascripts/bundle.cdb09f69.min.js.map",
"overrides/assets/stylesheets/main.css": "overrides/assets/stylesheets/main.21a5b0f1.min.css",
"overrides/assets/stylesheets/main.css.map": "overrides/assets/stylesheets/main.21a5b0f1.min.css.map"
"assets/stylesheets/main.css": "assets/stylesheets/main.8e656da0.min.css",
"assets/stylesheets/main.css.map": "assets/stylesheets/main.8e656da0.min.css.map",
"assets/stylesheets/palette.css": "assets/stylesheets/palette.936e7021.min.css",
"assets/stylesheets/palette.css.map": "assets/stylesheets/palette.936e7021.min.css.map",
"overrides/assets/javascripts/bundle.js": "overrides/assets/javascripts/bundle.576c0d5a.min.js",
"overrides/assets/javascripts/bundle.js.map": "overrides/assets/javascripts/bundle.576c0d5a.min.js.map",
"overrides/assets/stylesheets/main.css": "overrides/assets/stylesheets/main.2aa486e8.min.css",
"overrides/assets/stylesheets/main.css.map": "overrides/assets/stylesheets/main.2aa486e8.min.css.map"
}

View File

@ -39,10 +39,10 @@
{% endif %}
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.0258fc15.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.8e656da0.min.css' | url }}">
{% if config.theme.palette %}
{% set palette = config.theme.palette %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.5b7c1fa0.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.936e7021.min.css' | url }}">
{% if palette.primary %}
{% import "partials/palette.html" as map %}
{% set primary = map.primary(
@ -184,8 +184,8 @@
{% endblock %}
</div>
{% block scripts %}
<script src="{{ 'assets/javascripts/vendor.d018e87b.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.87ed5edf.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/vendor.f03b12a7.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.d3f6ab33.min.js' | url }}"></script>
{%- set translations = {} -%}
{%- for key in [
"clipboard.copy",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
!function(e,t){for(var r in t)e[r]=t[r]}(window,function(e){function t(t){for(var n,i,c=t[0],a=t[1],f=t[2],p=0,s=[];p<c.length;p++)i=c[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(l&&l(t);s.length;)s.shift()();return u.push.apply(u,f||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,c=1;c<r.length;c++){var a=r[c];0!==o[a]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={4:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="";var c=window.webpackJsonp=window.webpackJsonp||[],a=c.push.bind(c);c.push=t,c=c.slice();for(var f=0;f<c.length;f++)t(c[f]);var l=a;return u.push([50,0]),r()}({50:function(e,t,r){"use strict";r.r(t);var n=r(53);Object(n.a)(document.body,"click").subscribe(e=>{if(e.target instanceof HTMLElement){var t=e.target.closest("a[href^=http]");t instanceof HTMLLinkElement&&ga("send","event","outbound","click",t.href)}})}}));
//# sourceMappingURL=bundle.cdb09f69.min.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@
<meta name="twitter:title" content="{{ title }}">
<meta name="twitter:description" content="{{ config.site_description }}">
<meta name="twitter:image" content="{{ image }}">
<link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.21a5b0f1.min.css' | url }}">
<link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.2aa486e8.min.css' | url }}">
{% endblock %}
{% block announce %}
<a href="https://twitter.com/squidfunk">
@ -53,5 +53,14 @@
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ 'overrides/assets/javascripts/bundle.cdb09f69.min.js' | url }}"></script>
{% block config %}
{%- set configuration = {
"base": base_url,
"features": features
} -%}
<script id="__config" type="application/json">
{{- configuration | tojson -}}
</script>
{% endblock %}
<script src="{{ 'overrides/assets/javascripts/bundle.576c0d5a.min.js' | url }}"></script>
{% endblock %}

34
package-lock.json generated
View File

@ -402,6 +402,12 @@
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
"dev": true
},
"@types/fuzzaldrin-plus": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@types/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.1.tgz",
"integrity": "sha512-UFGM/hVBPlttAqSDMbYdupckngYNY/DAYBPHrHw4Pl2bK3mPwSabhkRHK1uK9udi5KZG/qX7D6z1/Jo5smTJFw==",
"dev": true
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
@ -4118,6 +4124,12 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"fuzzaldrin-plus": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz",
"integrity": "sha1-gy9kifvodnaUWVmckUpnDsIpR+4=",
"dev": true
},
"gensync": {
"version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
@ -4308,6 +4320,12 @@
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
"globalyzer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==",
"dev": true
},
"globby": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
@ -4363,6 +4381,12 @@
"integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=",
"dev": true
},
"globrex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"dev": true
},
"gonzales-pe": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz",
@ -10762,6 +10786,16 @@
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"tiny-glob": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz",
"integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==",
"dev": true,
"requires": {
"globalyzer": "0.1.0",
"globrex": "^0.1.2"
}
},
"to-arraybuffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",

View File

@ -34,6 +34,7 @@
"dependencies": {
"clipboard": "^2.0.6",
"escape-html": "^1.0.3",
"fuzzaldrin-plus": "^0.6.0",
"focus-visible": "^5.2.0",
"lunr": "^2.3.9",
"lunr-languages": "^1.4.0",
@ -47,6 +48,7 @@
"@types/copy-webpack-plugin": "^6.4.0",
"@types/escape-html": "1.0.0",
"@types/event-hooks-webpack-plugin": "^2.2.0",
"@types/fuzzaldrin-plus": "^0.6.1",
"@types/html-minifier": "^4.0.0",
"@types/lunr": "^2.3.3",
"@types/mini-css-extract-plugin": "^1.2.2",
@ -82,6 +84,7 @@
"stylelint-config-standard": "^20.0.0",
"stylelint-order": "^4.1.0",
"stylelint-scss": "^3.18.0",
"tiny-glob": "^0.2.8",
"ts-loader": "^8.0.14",
"ts-node": "^9.1.1",
"tsconfig-paths-webpack-plugin": "^3.3.0",

View File

@ -75,7 +75,8 @@ export function setupClipboard(
/* Initialize clipboard */
const clipboard$ = new Observable<ClipboardJS.Event>(subscriber => {
new ClipboardJS(".md-clipboard").on("success", ev => subscriber.next(ev))
new ClipboardJS("[data-clipboard-target], [data-clipboard-text]")
.on("success", ev => subscriber.next(ev))
})
.pipe(
share()

View File

@ -206,7 +206,7 @@
<!-- Overlay for expanded drawer -->
<label class="md-overlay" for="__drawer"></label>
<!-- Link to skip to content -->
<!-- Skip to content -->
<div data-md-component="skip">
{% if page.toc | first is defined %}
{% set skip = page.toc | first %}
@ -232,7 +232,7 @@
{% include "partials/header.html" %}
{% endblock %}
<!-- Container, necessary for web-application context -->
<!-- Container -->
<div class="md-container" data-md-component="container">
<!-- Hero teaser -->

View File

@ -1,4 +1,59 @@
import { fromEvent } from "rxjs"
/*
* Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
import { from, fromEvent } from "rxjs"
import { filter } from "fuzzaldrin-plus"
import { getElement, getElementOrThrow } from "browser"
import { map, switchMap } from "rxjs/operators"
import { renderIconSearch } from "./templates/icon"
// Obtain configuration
const el = getElementOrThrow("#__config")
const config = JSON.parse(el.textContent!)
// Now, load icons.json
const icons$ =
from(fetch(`${config.base}/overrides/assets/javascripts/icons.json`)
.then(res => res.json())
)
// Render icon search, if present
const search = getElement<HTMLInputElement>("#icon-search")
if (search) {
icons$
.pipe(
switchMap(icons => fromEvent<InputEvent>(search, "keyup")
.pipe(
map(() => filter(icons, search.value))
)
)
)
.subscribe((result: any[]) => {
const list = getElementOrThrow(".tx-icon-result")
list.innerHTML = ""
list.appendChild(renderIconSearch(result, search.value))
})
}
// Track click events
fromEvent(document.body, "click")
@ -6,6 +61,8 @@ fromEvent(document.body, "click")
if (ev.target instanceof HTMLElement) {
var el = ev.target.closest("a[href^=http]")
if (el instanceof HTMLLinkElement)
// @ts-ignore
ga("send", "event", "outbound", "click", el.href)
}
})

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
import { wrap } from "fuzzaldrin-plus"
import { h, round } from "utilities"
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
function transform(value: string, query: string) {
return `:${wrap(value.replace(/\.svg$/, "").replace(/\//g, "-"), query, {
wrap: {
tagOpen: "<b>",
tagClose: "</b>"
}
})}:`
}
const base = "https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/material/.icons/"
export function renderIconSearch(
results: string[], query: string
) {
if (!query.length)
return <div class=""></div>
return (
<div class="">
<span>{round(results.length)} results</span>
<ul class="tx-icon-search__list">
{results.slice(0, 10).map(result => (
<li class="tx-icon-search__item">
<span class="twemoji">
<img src={base + result} style="width: 18px; height: 18px" />
</span> <button
class="md-clipboard--inline"
data-clipboard-text={
":" + result.replace(/\.svg$/, "").replace(/\//g, "-") + ":"
}
>
<code>{transform(result, query)}</code>
</button>
</li>
))}
</ul>
</div>
)
}

View File

@ -41,3 +41,5 @@
@import "main/layout/announce";
@import "main/layout/content";
@import "main/layout/hero";
@import "main/shame";

View File

@ -0,0 +1,66 @@
////
/// Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
///
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS
////
// ----------------------------------------------------------------------------
// Nothing to see here, move along
// ----------------------------------------------------------------------------
// Scoped in typesetted content to match specificity of regular content
.md-typeset {
// Input
.md-input {
@include z-depth(1);
width: 100%;
height: px2rem(36px);
padding: 0 px2rem(12px);
font-size: px2rem(16px);
border-radius: px2rem(2px);
box-shadow:
0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1),
0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.1);
transition: box-shadow 250ms;
&:hover,
&:focus {
box-shadow:
0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15),
0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15);
}
}
.md-clipboard--inline {
cursor: pointer;
code {
transition:
color 250ms,
background-color 250ms;
}
&:focus code,
&:hover code {
color: var(--md-accent-fg-color);
background-color: var(--md-accent-fg-color--transparent);
}
}
}

View File

@ -96,6 +96,18 @@
{% block scripts %}
{{ super() }}
<!-- Application configuration -->
{% block config %}
{%- set configuration = {
"base": base_url,
"features": features
} -%}
<script id="__config" type="application/json">
{{- configuration | tojson -}}
</script>
{% endblock %}
<!-- Extra JavaScript -->
<script src="{{ 'overrides/assets/javascripts/bundle.js' | url }}"></script>
{% endblock %}

View File

@ -41,6 +41,7 @@
},
"include": [
"src/assets/javascripts",
"src/overrides/assets/javascripts",
"typings",
"webpack.config.ts"
],

View File

@ -29,6 +29,7 @@ import ImageminPlugin from "imagemin-webpack-plugin"
import MiniCssExtractPlugin = require("mini-css-extract-plugin")
import * as path from "path"
import { toPairs } from "ramda"
import glob = require("tiny-glob")
import { minify as minjs } from "terser"
import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin"
import { Configuration } from "webpack"
@ -328,7 +329,7 @@ export default (_env: never, args: Configuration): Configuration[] => {
/* Hooks */
new EventHooksPlugin({
afterEmit: () => {
afterEmit: async () => {
/* Replace asset URLs in templates */
if (args.mode === "production") {
@ -346,6 +347,13 @@ export default (_env: never, args: Configuration): Configuration[] => {
fs.writeFileSync(file, template, "utf8")
}
}
/* Build search index for bundled icons */
const index = await glob("**/*.svg", { cwd: "material/.icons" })
fs.writeFileSync(
"material/overrides/assets/javascripts/icons.json",
JSON.stringify(index)
)
}
}),