Compare commits

..

17 Commits

Author SHA1 Message Date
Cory LaViska
3217ce9f76 resolve feedback 2023-08-21 10:56:25 -04:00
Cory LaViska
c6d69fdbd6 update changelog 2023-08-18 14:47:58 -04:00
Cory LaViska
77b40fa7b4 Merge branch 'next' into submenus 2023-08-18 14:43:17 -04:00
Cory LaViska
bebf74a1fb stay highlighted when submenu is open 2023-08-18 14:40:21 -04:00
Cory LaViska
f524d20216 polish up submenu stuff 2023-08-18 14:18:38 -04:00
Cory LaViska
021c32ab32 Merge branch 'next-eycrb' of github.com:ecyrb/shoelace-ecyrb-fork into ecyrb-next-eycrb 2023-08-18 13:04:14 -04:00
Bryce Moore
dbf506d78f Submenu tweaks ...
- 100 ms delay when opening submenus on mouseover
- Shadows added
- Distance added to popup to have submenus overlap menu slightly.
2023-07-14 15:13:07 -04:00
Bryce Moore
1d826a9c53 fix: Prevent menu's extraneous Enter / space key propagation.
Menu's handleKeyDown calls item.click (to emit the selection).
Propagating the keyboard event on Enter / space would the cause re-entry
into a submenu, so prevent the needless propagation.
2023-07-13 09:55:45 -04:00
Bryce Moore
58d6cad39a fix: 2 changes to menu / submenu on-click behavior:
1. Close submenu on click explicitly, so this occurs even if the menu is
   not inside of an sl-dropdown.

2. In menu, ignore clicks that do not explicitly target a menu-item.
   Clicks that were on (e.g. a menu-border) were emitting select events.
2023-07-13 08:49:10 -04:00
Bryce Moore
e0e96c8a0a style: Eslint warnings and errors fixed. npm run verify now passes. 2023-07-13 06:26:44 -04:00
Bryce Moore
25a146ffd1 Cleanup: Removed dead code and dead code comments. 2023-07-11 02:50:48 -04:00
Bryce Moore
c55ba0467e Merge branch 'next' into next-eycrb 2023-07-08 08:16:46 -04:00
Bryce Moore
126b0e34bd [WIP] Submenu WIP continues.
- Submenus now close on change-of-focus, not a timeout.
- Keyboard navigation support added.
- Skidding fix for better alignment.
- Submenu documentation moved to Menu page.
- Tests for accessibility, right and left arrow keys.
2023-07-07 09:43:40 -04:00
Bryce Moore
7aca8d7300 Revert "PoC working of ArrowRight to focus on submenu."
(Didn't mean to publish this.)

This reverts commit be04e9a221.
2023-06-30 09:52:54 -04:00
Bryce Moore
be04e9a221 PoC working of ArrowRight to focus on submenu. 2023-06-30 07:44:55 -04:00
Bryce
354404484e Update submenu-controller.ts
Removed extraneous `console.log()`.
2023-06-28 02:43:51 -04:00
Bryce Moore
b48d072bc8 [RFC] Proof-of-concept commit for submenu support
This is a Request For Comments to seek directional guidance towards
implementing the submenu slot of menu-item.

Includes:
- SubmenuController to manage event listeners on menu-item.
- Example usage in menu-item documentation.
- Trivial tests to check rendering.

Outstanding questions include:
- Accessibility concerns. E.g. where to handle 'ArrowRight',
  'ArrowLeft'?
- Should selection of menu-item denoting submenu be possible or
  customizable?
- How to parameterize contained popup?
- Implementation concerns:
  - Use of ref / id
  - delegation of some rendering to the controller
  - What to test

Related to [#620](https://github.com/shoelace-style/shoelace/issues/620).
2023-06-28 01:08:37 -04:00
1477 changed files with 66240 additions and 52999 deletions

View File

@@ -42,19 +42,17 @@ module.exports = {
rules: {
'default-param-last': 'off',
'@typescript-eslint/default-param-last': 'error',
'no-console': 'warn',
'no-empty-function': 'off',
'@typescript-eslint/no-empty-function': 'warn',
'no-implied-eval': 'off',
'no-invalid-this': 'off',
'no-shadow': 'off',
'no-throw-literal': 'off',
'no-unused-expressions': 'off',
'lit-a11y/no-autofocus': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'no-invalid-this': 'off',
'@typescript-eslint/no-invalid-this': 'error',
'@typescript-eslint/no-throw-literal': 'error',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/no-throw-literal': 'error',
'no-unused-expressions': 'off',
'@typescript-eslint/prefer-regexp-exec': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/unbound-method': 'off',

View File

@@ -35,7 +35,7 @@ This Code of Conduct applies within all project spaces, and it also applies when
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at support@fontawesome.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at cory@abeautifulsite.net. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: [claviska]

View File

@@ -1,7 +1,4 @@
contact_links:
- name: Feature Requests
url: https://github.com/shoelace-style/shoelace/discussions/categories/ideas
about: All requests for new features should go here.
- name: Help & Support
url: https://github.com/shoelace-style/shoelace/discussions/categories/help
about: Please don't create issues for personal help requests. Instead, ask your question on the discussion forum.

View File

@@ -0,0 +1,15 @@
---
name: Feature Request
about: Suggest an idea for this project.
title: ''
labels: feature
---
### What issue are you having?
Provide a clear and concise description of the problem you're facing.
### Describe the solution you'd like
How would you like to see the library solve it?
### Describe alternatives you've considered
In what ways have you tried to solve this with the current version?

4
.github/SECURITY.md vendored
View File

@@ -1,7 +1,7 @@
# Reporting Security Issues
We take security issues in Web Awesome very seriously and appreciate your efforts to disclose your findings responsibly.
We take security issues in Shoelace very seriously and appreciate your efforts to disclose your findings responsibly.
To report a security issue, email [support@fontawesome.com](mailto:support@fontawesome.com) and include "WEB AWESOME SECURITY" in the subject line.
To report a security issue, email [cory@abeautifulsite.net](mailto:cory@abeautifulsite.net) and include "SHOELACE SECURITY" in the subject line.
We'll respond as soon as possible and keep you updated throughout the process.

6
.gitignore vendored
View File

@@ -1,11 +1,9 @@
_site
.cache
.DS_Store
package.json
package-lock.json
dist
docs/public/pagefind
docs/assets/images/sprite.svg
node_modules
src/react
cdn
.astro
web-types.json

View File

@@ -1,5 +1,4 @@
*.hbs
*.md
.cache
.github
cspell.json

View File

@@ -2,7 +2,6 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"debug.enableStatusBarColor": false
"source.fixAll.eslint": true
}
}

View File

@@ -1,4 +1,4 @@
# Contributing to Web Awesome
# Contributing to Shoelace
Before contributing, please review the contributions guidelines at:

View File

@@ -1,4 +1,4 @@
Copyright (c) 2023 Fonticons, Inc.
Copyright (c) 2020 A Beautiful Site, LLC
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:

View File

@@ -1,4 +1,6 @@
# Web Awesome
# Shoelace
A forward-thinking library of web components.
- Works with all frameworks 🧩
- Works with CDNs 🚛
@@ -7,7 +9,7 @@
- Built with accessibility in mind ♿️
- Open source 😸
Built by the folks behind [Font Awesome](https://fontawesome.com/).
Designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska).
---
@@ -19,15 +21,15 @@ Twitter: [@shoelace_style](https://twitter.com/shoelace_style)
---
## Developers
## Shoemakers 🥾
Developers can use this documentation to learn how to build Web Awesome from source. You will need Node >= 14.17 to build and run the project locally.
Shoemakers, or "Shoelace developers," can use this documentation to learn how to build Shoelace from source. You will need Node >= 14.17 to build and run the project locally.
**You don't need to do any of this to use Web Awesome!** This page is for people who want to contribute to the project, tinker with the source, or create a custom build of Web Awesome.
**You don't need to do any of this to use Shoelace!** This page is for people who want to contribute to the project, tinker with the source, or create a custom build of Shoelace.
If that's not what you're trying to do, the [documentation website](https://shoelace.style) is where you want to be.
### What are you using to build Web Awesome?
### What are you using to build Shoelace?
Components are built with [LitElement](https://lit-element.polymer-project.org/), a custom elements base class that provides an intuitive API and reactive data binding. The build is a custom script with bundling powered by [esbuild](https://esbuild.github.io/).
@@ -36,8 +38,8 @@ Components are built with [LitElement](https://lit-element.polymer-project.org/)
Start by [forking the repo](https://github.com/shoelace-style/shoelace/fork) on GitHub, then clone it locally and install dependencies.
```bash
git clone https://github.com/YOUR_GITHUB_USERNAME/webawesome
cd webawesome
git clone https://github.com/YOUR_GITHUB_USERNAME/shoelace
cd shoelace
npm install
```
@@ -61,18 +63,30 @@ npm run build
### Creating New Components
To scaffold a new component, run the following command, replacing `wa-tag-name` with the desired tag name.
To scaffold a new component, run the following command, replacing `sl-tag-name` with the desired tag name.
```bash
npm run create wa-tag-name
npm run create sl-tag-name
```
This will generate a source file, a stylesheet, and a docs page for you. When you start the dev server, you'll find the new component in the "Components" section of the sidebar.
### Contributing
Web Awesome is an open source project and contributions are encouraged! If you're interesting in contributing, please review the [contribution guidelines](CONTRIBUTING.md) first.
Shoelace is an open source project and contributions are encouraged! If you're interesting in contributing, please review the [contribution guidelines](CONTRIBUTING.md) first.
## License
Web Awesome is available under the terms of the MIT license.
Shoelace is designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska). Its available under the terms of the MIT license.
Designing, developing, and supporting this library requires a lot of time, effort, and skill. Id like to keep it open source so everyone can use it, but that doesnt provide me with any income.
**Therefore, if youre using my software to make a profit,** I respectfully ask that you help [fund its development](https://github.com/sponsors/claviska) by becoming a sponsor. There are multiple tiers to choose from with benefits at every level, including prioritized support, bug fixes, feature requests, and advertising.
👇 Your support is very much appreciated! 👇
- [Become a sponsor](https://github.com/sponsors/claviska)
- [Star on GitHub](https://github.com/shoelace-style/shoelace/stargazers)
- [Follow on Twitter](https://twitter.com/shoelace_style)
Whether you're building Shoelace or building something _with_ Shoelace — have fun creating! 🥾

View File

@@ -21,6 +21,7 @@
"cdndir",
"chatbubble",
"checkmark",
"claviska",
"Clippy",
"codebases",
"codepen",
@@ -28,7 +29,6 @@
"colour",
"combobox",
"Commonmark",
"compat",
"Composability",
"Consolas",
"contenteditable",
@@ -46,7 +46,6 @@
"dropdowns",
"easings",
"endraw",
"endregion",
"enterkeyhint",
"eqeqeq",
"erroneou",
@@ -85,11 +84,11 @@
"Kool",
"labelledby",
"Laravel",
"LaViska",
"linkify",
"listbox",
"listitem",
"litelement",
"longform",
"lowercasing",
"Lucide",
"maxlength",
@@ -101,7 +100,6 @@
"monospace",
"mousedown",
"mousemove",
"mouseout",
"mouseup",
"multiselectable",
"nextjs",
@@ -111,14 +109,10 @@
"novalidate",
"npmdir",
"Numberish",
"oklab",
"oklch",
"onscrollend",
"outdir",
"ParamagicDev",
"peta",
"petabit",
"Preact",
"prismjs",
"progressbar",
"radiogroup",
@@ -141,8 +135,6 @@
"scroller",
"Segoe",
"semibold",
"Shortcode",
"Shortcodes",
"sitedir",
"slotchange",
"smartquotes",
@@ -158,7 +150,6 @@
"testid",
"textareas",
"textfield",
"Themer",
"tinycolor",
"transitionend",
"treeitem",
@@ -174,13 +165,9 @@
"valpha",
"valuenow",
"valuetext",
"viewports",
"Vuejs",
"WCAG",
"webawesome",
"WEBP",
"Webpacker",
"xmark"
"wordmark"
],
"ignorePaths": [
"package.json",

View File

@@ -1,13 +1,23 @@
import * as path from 'path';
import { customElementJetBrainsPlugin } from 'custom-element-jet-brains-integration';
import { customElementVsCodePlugin } from 'custom-element-vs-code-integration';
import { customElementVuejsPlugin } from 'custom-element-vuejs-integration';
import { parse } from 'comment-parser';
import { pascalCase } from 'pascal-case';
import commandLineArgs from 'command-line-args';
import fs from 'fs';
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const { name, description, version, author, homepage, license } = packageData;
const outdir = 'dist';
const { outdir } = commandLineArgs([
{ name: 'litelement', type: String },
{ name: 'analyze', defaultOption: true },
{ name: 'outdir', type: String }
]);
function noDash(string) {
return string.replace(/^\s?-/, '').trim();
}
function replace(string, terms) {
terms.forEach(({ from, to }) => {
@@ -18,28 +28,53 @@ function replace(string, terms) {
}
export default {
globs: ['src/components/**/*.ts'],
globs: ['src/components/**/*.component.ts'],
exclude: ['**/*.styles.ts', '**/*.test.ts'],
litelement: true,
outdir,
plugins: [
// Append package data
{
name: 'wa-package-data',
name: 'shoelace-package-data',
packageLinkPhase({ customElementsManifest }) {
customElementsManifest.package = { name, description, version, author, homepage, license };
}
},
// Parse custom jsDoc tags
// Infer tag names because we no longer use @customElement decorators.
{
name: 'wa-custom-tags',
name: 'shoelace-infer-tag-names',
analyzePhase({ ts, node, moduleDoc }) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration: {
const className = node.name.getText();
const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
const customTags = ['dependency', 'documentation', 'since', 'status', 'title'];
const importPath = moduleDoc.path;
// This is kind of a best guess at components. "thing.component.ts"
if (!importPath.endsWith('.component.ts')) {
return;
}
const tagNameWithoutPrefix = path.basename(importPath, '.component.ts');
const tagName = 'sl-' + tagNameWithoutPrefix;
classDoc.tagNameWithoutPrefix = tagNameWithoutPrefix;
classDoc.tagName = tagName;
// This used to be set to true by @customElement
classDoc.customElement = true;
}
}
}
},
// Parse custom jsDoc tags
{
name: 'shoelace-custom-tags',
analyzePhase({ ts, node, moduleDoc }) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration: {
const className = node.name.getText();
const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
const customTags = ['animation', 'dependency', 'documentation', 'since', 'status', 'title'];
let customComments = '/**';
node.jsDoc?.forEach(jsDoc => {
@@ -58,6 +93,17 @@ export default {
const parsed = parse(`${customComments}\n */`);
parsed[0].tags?.forEach(t => {
switch (t.tag) {
// Animations
case 'animation':
if (!Array.isArray(classDoc['animations'])) {
classDoc['animations'] = [];
}
classDoc['animations'].push({
name: t.name,
description: noDash(t.description)
});
break;
// Dependencies
case 'dependency':
if (!Array.isArray(classDoc['dependencies'])) {
@@ -91,9 +137,8 @@ export default {
}
}
},
{
name: 'wa-react-event-names',
name: 'shoelace-react-event-names',
analyzePhase({ ts, node, moduleDoc }) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration: {
@@ -102,7 +147,6 @@ export default {
if (classDoc?.events) {
classDoc.events.forEach(event => {
if (!event.name) return;
event.reactName = `on${pascalCase(event.name)}`;
event.eventName = `${pascalCase(event.name)}Event`;
});
@@ -111,9 +155,8 @@ export default {
}
}
},
{
name: 'wa-translate-module-paths',
name: 'shoelace-translate-module-paths',
packageLinkPhase({ customElementsManifest }) {
customElementsManifest?.modules?.forEach(mod => {
//
@@ -127,7 +170,7 @@ export default {
//
const terms = [
{ from: /^src\//, to: '' }, // Strip the src/ prefix
{ from: /\.(t|j)sx?$/, to: '.js' } // Convert .ts to .js
{ from: /\.component.(t|j)sx?$/, to: '.js' } // Convert .ts to .js
];
mod.path = replace(mod.path, terms);
@@ -148,7 +191,6 @@ export default {
});
}
},
// Generate custom VS Code data
customElementVsCodePlugin({
outdir,
@@ -156,30 +198,18 @@ export default {
referencesTemplate: (_, tag) => [
{
name: 'Documentation',
url: `https://shoelace.style/components/${tag.replace('wa-', '')}`
url: `https://shoelace.style/components/${tag.replace('sl-', '')}`
}
]
}),
customElementJetBrainsPlugin({
outdir: './dist',
excludeCss: true,
packageJson: false,
referencesTemplate: (_, tag) => {
return {
name: 'Documentation',
url: `https://shoelace.style/components/${tag.replace('wa-', '')}`
url: `https://shoelace.style/components/${tag.replace('sl-', '')}`
};
}
})
//
// TODO - figure out why this broke when events were updated
//
// customElementVuejsPlugin({
// outdir: './dist/types/vue',
// fileName: 'index.d.ts',
// componentTypePath: (_, tag) => `../../components/${tag.replace('wa-', '')}/${tag.replace('wa-', '')}.js`
// })
]
};

View File

@@ -1,126 +0,0 @@
import { parse } from 'path';
import { markdown } from './_utils/markdown.js';
import { anchorHeadingsPlugin } from './_utils/anchor-headings.js';
import { codeExamplesPlugin } from './_utils/code-examples.js';
import { copyCodePlugin } from './_utils/copy-code.js';
import { currentLink } from './_utils/current-link.js';
import { highlightCodePlugin } from './_utils/highlight-code.js';
import { formatCodePlugin } from './_utils/format-code.js';
import { replaceTextPlugin } from './_utils/replace-text.js';
import { searchPlugin } from './_utils/search.js';
import { readFile } from 'fs/promises';
import { outlinePlugin } from './_utils/outline.js';
import { getComponents } from './_utils/manifest.js';
import process from 'process';
const packageData = JSON.parse(await readFile('./package.json', 'utf-8'));
const isDeveloping = process.argv.includes('--develop');
export default function (eleventyConfig) {
// Add template data
eleventyConfig.addGlobalData('package', packageData);
// Template filters - {{ content | filter }}
eleventyConfig.addFilter('inlineMarkdown', content => markdown.renderInline(content || ''));
eleventyConfig.addFilter('markdown', content => markdown.render(content || ''));
eleventyConfig.addFilter('stripExtension', string => parse(string).name);
eleventyConfig.addFilter('stripPrefix', content => content.replace(/^wa-/, ''));
eleventyConfig.addFilter('trimPipes', content => {
// Trims whitespace and pipes from the start and end of a string. Useful for CEM types, which can be pipe-delimited.
// With Prettier 3, this means a leading pipe will exist be present when the line wraps.
return typeof content === 'string' ? content.replace(/^(\s|\|)/g, '').replace(/(\s|\|)$/g, '') : content;
});
// Shortcodes - {% shortCode arg1, arg2 %}
eleventyConfig.addShortcode('cdnUrl', location => {
return (
`https://cdn.jsdelivr.net/npm/@shoelace-style/webawesome@${packageData.version}/` + location.replace(/^\//, '')
);
});
// Helpers
eleventyConfig.addNunjucksGlobal('getComponent', tagName => {
const component = getComponents().find(c => c.tagName === tagName);
if (!component) {
throw new Error(
`Unable to find "<${tagName}>". Make sure the file name is the same as the tag name (without prefix).`
);
}
return component;
});
// Use our own markdown instance
eleventyConfig.setLibrary('md', markdown);
// Add anchors to headings
eleventyConfig.addPlugin(anchorHeadingsPlugin({ container: '#content' }));
// Add an outline to the page
eleventyConfig.addPlugin(
outlinePlugin({
container: '#content',
target: '.outline-links',
selector: 'h2, h3',
ifEmpty: doc => {
doc.querySelector('#outline')?.remove();
}
})
);
// Add current link classes
eleventyConfig.addPlugin(currentLink());
// Add code examples for `<code class="example">` blocks
eleventyConfig.addPlugin(codeExamplesPlugin());
// Highlight code blocks with Prism
eleventyConfig.addPlugin(highlightCodePlugin());
// Add copy code buttons to code blocks
eleventyConfig.addPlugin(copyCodePlugin());
// Various text replacements
eleventyConfig.addPlugin(
replaceTextPlugin([
// Replace [issue:1234] with a link to the issue on GitHub
{
replace: /\[pr:([0-9]+)\]/gs,
replaceWith: '<a href="https://github.com/shoelace-style/webawesome/pull/$1">#$1</a>'
},
// Replace [pr:1234] with a link to the pull request on GitHub
{
replace: /\[issue:([0-9]+)\]/gs,
replaceWith: '<a href="https://github.com/shoelace-style/webawesome/issues/$1">#$1</a>'
},
// Replace [discuss:1234] with a link to the discussion on GitHub
{
replace: /\[discuss:([0-9]+)\]/gs,
replaceWith: '<a href="https://github.com/shoelace-style/webawesome/discussions/$1">#$1</a>'
}
])
);
// Build the search index
eleventyConfig.addPlugin(
searchPlugin({
filename: '',
selectorsToIgnore: ['code.example'],
getContent: doc => doc.querySelector('#content')?.textContent ?? ''
})
);
// Production-only plugins
if (!isDeveloping) {
// Run Prettier on each file (prod only because it can be slow)
eleventyConfig.addPlugin(formatCodePlugin());
}
return {
dir: {
includes: '_includes',
layouts: '_layouts'
},
templateFormats: ['njk', 'md']
};
}

View File

@@ -1,11 +0,0 @@
---
title: Not Found
description: Sorry, I couldn't find that.
layout: page.njk
permalink: 404.html
noindex: true
---
<p class="subtitle">{{ description }}</p>
<p>Have you tried searching?</p>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,347 @@
{% extends "default.njk" %}
{# Find the component based on the `tag` front matter #}
{% set component = getComponent('sl-' + page.fileSlug) %}
{% block content %}
{# Determine the badge variant #}
{% if component.status == 'stable' %}
{% set badgeVariant = 'primary' %}
{% elseif component.status == 'experimental' %}
{% set badgeVariant = 'warning' %}
{% elseif component.status == 'planned' %}
{% set badgeVariant = 'neutral' %}
{% elseif component.status == 'deprecated' %}
{% set badgeVariant = 'danger' %}
{% else %}
{% set badgeVariant = 'neutral' %}
{% endif %}
{# Header #}
<header class="component-header">
<h1>{{ component.name | classNameToComponentName }}</h1>
<div class="component-header__tag">
<code>&lt;{{ component.tagName }}&gt; | {{ component.name }}</code>
</div>
<div class="component-header__info">
<sl-badge variant="neutral" pill>
Since {{component.since or '?' }}
</sl-badge>
<sl-badge variant="{{ badgeVariant }}" pill style="text-transform: capitalize;">
{{ component.status }}
</sl-badge>
</div>
</header>
<p class="component-summary">
{% if component.summary %}
{{ component.summary | markdownInline | safe }}
{% endif %}
</p>
{# Markdown content #}
{{ content | safe }}
{# Importing #}
<h2>Importing</h2>
<p>
If you're using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use
any of the following snippets to <a href="/getting-started/installation#cherry-picking">cherry pick</a> this component.
</p>
<sl-tab-group>
<sl-tab slot="nav" panel="script">Script</sl-tab>
<sl-tab slot="nav" panel="import">Import</sl-tab>
<sl-tab slot="nav" panel="bundler">Bundler</sl-tab>
<sl-tab slot="nav" panel="react">React</sl-tab>
<sl-tab-panel name="script">
<p>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
using a script tag:
</p>
<pre><code class="language-html">&lt;script type=&quot;module&quot; src=&quot;https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}&quot;&gt;&lt;/script&gt;</code></pre>
</sl-tab-panel>
<sl-tab-panel name="import">
<p>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
using a JavaScript import:
</p>
<pre><code class="language-js">import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}';</code></pre>
</sl-tab-panel>
<sl-tab-panel name="bundler">
<p>
To import this component using <a href="{{ rootUrl('/getting-started/installation#bundling') }}">a bundler</a>:
</p>
<pre><code class="language-js">import '@shoelace-style/shoelace/{{ meta.npmdir }}/{{ component.path }}';</code></pre>
</sl-tab-panel>
<sl-tab-panel name="react">
<p>
To import this component as a <a href="/frameworks/react">React component</a>:
</p>
<pre><code class="language-js">import {{ component.name }} from '@shoelace-style/shoelace/{{ meta.npmdir }}/react/{{ component.tagNameWithoutPrefix }}';</code></pre>
</sl-tab-panel>
</sl-tab-group>
{# Slots #}
{% if component.slots.length %}
<h2>Slots</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for slot in component.slots %}
<tr>
<td class="nowrap">
{% if slot.name %}
<code>{{ slot.name }}</code>
{% else %}
(default)
{% endif %}
</td>
<td>{{ slot.description | markdownInline | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#slots') }}">using slots</a>.</em></p>
{% endif %}
{# Properties #}
{% if component.properties.length %}
<h2>Properties</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-reflects">Reflects</th>
<th class="table-type">Type</th>
<th class="table-default">Default</th>
</tr>
</thead>
<tbody>
{% for prop in component.properties %}
<tr>
<td>
<code class="nowrap">{{ prop.name }}</code>
{% if prop.attribute != prop.name %}
<br>
<sl-tooltip content="This attribute is different from its property">
<small>
<code class="nowrap">
{{ prop.attribute }}
</code>
</small>
</sl-tooltip>
{% endif %}
</td>
<td>
{{ prop.description | markdownInline | safe }}
</td>
<td style="text-align: center;">
{% if prop.reflects %}
<sl-icon label="yes" name="check-lg"></sl-icon>
{% endif %}
</td>
<td>
{% if prop.type.text %}
<code>{{ prop.type.text | markdownInline | safe }}</code>
{% else %}
-
{% endif %}
</td>
<td>
{% if prop.default %}
<code>{{ prop.default | markdownInline | safe }}</code>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
<tr>
<td class="nowrap"><code>updateComplete</code></td>
<td>
A read-only promise that resolves when the component has
<a href="/getting-started/usage?#component-rendering-and-updating">finished updating</a>.
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#properties') }}">attributes and properties</a>.</em></p>
{% endif %}
{# Events #}
{% if component.events.length %}
<h2>Events</h2>
<table>
<thead>
<tr>
<th class="table-name" data-flavor="html">Name</th>
<th class="table-name" data-flavor="react">React Event</th>
<th class="table-description">Description</th>
<th class="table-event-detail">Event Detail</th>
</tr>
</thead>
<tbody>
{% for event in component.events %}
<tr>
<td data-flavor="html"><code class="nowrap">{{ event.name }}</code></td>
<td data-flavor="react"><code class="nowrap">{{ event.reactName }}</code></td>
<td>{{ event.description | markdownInline | safe }}</td>
<td>
{% if event.type.text %}
<code>{{ event.type.text }}</code>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#events') }}">events</a>.</em></p>
{% endif %}
{# Methods #}
{% if component.methods.length %}
<h2>Methods</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-arguments">Arguments</th>
</tr>
</thead>
<tbody>
{% for method in component.methods %}
<tr>
<td class="nowrap"><code>{{ method.name }}()</code></td>
<td>{{ method.description | markdownInline | safe }}</td>
<td>
{% if method.parameters.length %}
<code>
{% for param in method.parameters %}
{{ param.name }}: {{ param.type.text }}{% if not loop.last %},{% endif %}
{% endfor %}
</code>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#methods') }}">methods</a>.</em></p>
{% endif %}
{# Custom Properties #}
{% if component.cssProperties.length %}
<h2>Custom Properties</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-default">Default</th>
</tr>
</thead>
<tbody>
{% for cssProperty in component.cssProperties %}
<tr>
<td class="nowrap"><code>{{ cssProperty.name }}</code></td>
<td>{{ cssProperty.description | markdownInline | safe }}</td>
<td>{{ cssProperty.default }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#custom-properties') }}">customizing CSS custom properties</a>.</em></p>
{% endif %}
{# CSS Parts #}
{% if component.cssParts.length %}
<h2>Parts</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for cssPart in component.cssParts %}
<tr>
<td class="nowrap"><code>{{ cssPart.name }}</code></td>
<td>{{ cssPart.description | markdownInline | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#component-parts') }}">customizing CSS parts</a>.</em></p>
{% endif %}
{# Animations #}
{% if component.animations.length %}
<h2>Animations</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for animation in component.animations %}
<tr>
<td class="nowrap"><code>{{ animation.name }}</code></td>
<td>{{ animation.description | markdownInline | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#animations') }}">customizing animations</a>.</em></p>
{% endif %}
{# Dependencies #}
{% if component.dependencies.length %}
<h2>Dependencies</h2>
<p>This component automatically imports the following dependencies.</p>
<ul>
{% for dependency in component.dependencies %}
<li><code>&lt;{{ dependency }}&gt;</code></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

150
docs/_includes/default.njk Normal file
View File

@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html
lang="en"
data-layout="{{ layout }}"
data-shoelace-version="{{ meta.version }}"
>
<head>
{# Metadata #}
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{ meta.description }}" />
<title>{{ meta.title }}</title>
{# Opt out of Turbo caching #}
<meta name="turbo-cache-control">
{# Stylesheets #}
<link rel="stylesheet" href="{{ assetUrl('styles/docs.css') }}" />
<link rel="stylesheet" href="{{ assetUrl('styles/code-previews.css') }}" />
<link rel="stylesheet" href="{{ assetUrl('styles/search.css') }}" />
{# Favicons #}
<link rel="icon" href="{{ assetUrl('images/logo.svg') }}" type="image/x-icon" />
{# Twitter Cards #}
<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content="shoelace_style" />
<meta name="twitter:image" content="{{ assetUrl(meta.image, true) }}" />
{# OpenGraph #}
<meta property="og:url" content="{{ rootUrl(page.url, true) }}" />
<meta property="og:title" content="{{ meta.title }}" />
<meta property="og:description" content="{{ meta.description }}" />
<meta property="og:image" content="{{ assetUrl(meta.image, true) }}" />
{# Shoelace #}
<link rel="stylesheet" href="/dist/themes/light.css" />
<link rel="stylesheet" href="/dist/themes/dark.css" />
<script type="module" src="/dist/shoelace-autoloader.js"></script>
{# Set the initial theme and menu states here to prevent flashing #}
<script>
(() => {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = localStorage.getItem('theme') || 'auto';
document.documentElement.classList.toggle('sl-theme-dark', theme === 'dark' || (theme === 'auto' && prefersDark));
})();
</script>
{# Turbo + Scroll positioning #}
<script src="{{ assetUrl('scripts/turbo.js') }}" type="module"></script>
<script src="{{ assetUrl('scripts/docs.js') }}" defer></script>
<script src="{{ assetUrl('scripts/code-previews.js') }}" defer></script>
<script src="{{ assetUrl('scripts/lunr.js') }}" defer></script>
<script src="{{ assetUrl('scripts/search.js') }}" defer></script>
</head>
<body>
<a id="skip-to-main" class="visually-hidden" href="#main-content" data-smooth-link="false">
Skip to main content
</a>
{# Menu toggle #}
<button id="menu-toggle" type="button" aria-label="Menu">
<svg width="148" height="148" viewBox="0 0 148 148" xmlns="http://www.w3.org/2000/svg">
<g stroke="currentColor" stroke-width="18" fill="none" fill-rule="evenodd" stroke-linecap="round">
<path d="M9.5 125.5h129M9.5 74.5h129M9.5 23.5h129"></path>
</g>
</svg>
</button>
{# Icon toolbar #}
<div id="icon-toolbar">
{# GitHub #}
<a href="https://github.com/shoelace-style/shoelace" title="View Shoelace on GitHub">
<sl-icon name="github"></sl-icon>
</a>
{# Twitter #}
<a href="https://twitter.com/shoelace_style" title="Follow Shoelace on Twitter">
<sl-icon name="twitter"></sl-icon>
</a>
{# Theme selector #}
<sl-dropdown id="theme-selector" placement="bottom-end" distance="3">
<sl-button slot="trigger" size="small" variant="text" caret title="Press \ to toggle">
<sl-icon class="only-light" name="sun-fill"></sl-icon>
<sl-icon class="only-dark" name="moon-fill"></sl-icon>
</sl-button>
<sl-menu>
<sl-menu-item type="checkbox" value="light">Light</sl-menu-item>
<sl-menu-item type="checkbox" value="dark">Dark</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item type="checkbox" value="auto">System</sl-menu-item>
</sl-menu>
</sl-dropdown>
</div>
<aside id="sidebar" data-preserve-scroll>
<header>
<a href="/">
<img src="{{ assetUrl('images/wordmark.svg') }}" alt="Shoelace" />
</a>
<div class="sidebar-version">
{{ meta.version }}
</div>
</header>
<div class="sidebar-buttons">
<sl-button size="small" class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace" target="_blank">
<sl-icon slot="prefix" name="github"></sl-icon> Code
</sl-button>
<sl-button size="small" class="repo-button repo-button--star" href="https://github.com/shoelace-style/shoelace/stargazers" target="_blank">
<sl-icon slot="prefix" name="star-fill"></sl-icon> Star
</sl-button>
<sl-button size="small" class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" target="_blank">
<sl-icon slot="prefix" name="twitter"></sl-icon> Follow
</sl-button>
</div>
<button class="search-box" type="button" title="Press / to search" aria-label="Search" data-plugin="search">
<sl-icon name="search"></sl-icon>
<span>Search</span>
</button>
<nav>
{% include 'sidebar.njk' %}
</nav>
</aside>
{# Content #}
<main>
<a id="main-content"></a>
<article id="content" class="content{% if toc %} content--with-toc{% endif %}">
{% if toc %}
<div class="content__toc">
<ul>
<li class="top"><a href="#">{{ meta.title }}</a></li>
</ul>
</div>
{% endif %}
<div class="content__body">
{% block content %}
{{ content | safe }}
{% endblock %}
</div>
</article>
</main>
</body>
</html>

View File

@@ -1 +0,0 @@
<svg class="logo" xmlns="http://www.w3.org/2000/svg" width="277" height="211" viewBox="0 0 277 211"><g fill="none" fill-rule="evenodd"><path fill="#F6894C" d="M159.275,20.7541243 C159.275,28.4927904 155.035053,35.2422161 148.749528,38.8106604 L193.9,72.6391714 L238.157213,58.6776414 C236.43401,55.6537326 235.45,52.1547058 235.45,48.42629 C235.45,36.96411 244.751396,27.6721657 256.225,27.6721657 C267.698604,27.6721657 277,36.96411 277,48.42629 C277,59.8883646 267.698604,69.1804143 256.225,69.1804143 C255.131246,69.1804143 254.057541,69.0960801 253.00969,68.9332096 L204.251886,193.411571 C200.096886,204.019762 189.858966,211 178.45659,211 L98.5434095,211 C87.1410343,211 76.9031143,204.019762 72.7481143,193.411571 L23.990205,68.9332096 C22.9423008,69.0960801 21.8685432,69.1804143 20.775,69.1804143 C9.30129067,69.1804143 0,59.8883646 0,48.42629 C0,36.96411 9.30129067,27.6721657 20.775,27.6721657 C32.2487093,27.6721657 41.55,36.96411 41.55,48.42629 C41.55,52.1547058 40.5658322,55.6537326 38.842945,58.6776414 L83.1,72.6391714 L128.250472,38.8106604 C121.964947,35.2422161 117.725,28.4927904 117.725,20.7541243 C117.725,9.29194428 127.026396,0 138.5,0 C149.973604,0 159.275,9.29194428 159.275,20.7541243 Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -1,61 +0,0 @@
<wa-dialog id="site-search" no-header>
<div id="site-search-container">
{# Header #}
<header>
<div id="site-search-input-wrapper">
<wa-input
id="site-search-input"
type="search"
filled
size="large"
clearable
placeholder="Search"
autofocus
autocomplete="off"
autocorrect="off"
autocapitalize="off"
enterkeyhint="go"
spellcheck="false"
maxlength="100"
role="combobox"
aria-autocomplete="list"
aria-expanded="true"
aria-controls="site-search-listbox"
aria-haspopup="listbox"
aria-activedescendant
>
<wa-icon slot="prefix" name="search"></wa-icon>
</wa-input>
</div>
</header>
{# Body #}
<div id="site-search-body">
<ul
id="site-search-listbox"
role="listbox"
aria-label="Search results"
></ul>
<div id="site-search-empty">
<wa-icon name="web-awesome" family="brands"></wa-icon>
No results
</div>
</div>
{# Footer #}
<footer>
<small>
<kbd aria-label="Up"><wa-icon name="arrow-up" family="micro"></wa-icon></kbd>
<kbd aria-label="Down"><wa-icon name="arrow-down" family="micro"></wa-icon></kbd>
Navigate
</small>
<small>
<kbd>Enter</kbd>
Select
</small>
<small><kbd>Esc</kbd> Close</small>
</footer>
</div>
</wa-dialog>

View File

@@ -1,234 +1,65 @@
{# Getting started #}
<h2>Getting Started</h2>
<ul>
<li><a href="/docs/installation">Installation</a></li>
<li><a href="/docs/usage">Usage</a></li>
<li><a href="/docs/themes">Themes</a></li>
<li><a href="/docs/customizing">Customizing</a></li>
<li><a href="/docs/localization">Localization</a></li>
</ul>
{# Experimental #}
<h2>Experimental</h2>
<ul>
<li><a href="/docs/experimental/themer">Theme Builder</a></li>
<li><a href="/docs/experimental/style-guide">Style Guide</a></li>
<li><a href="/docs/experimental/form-validation">Form Validation Styles</a></li>
<li><a href="/docs/experimental/sandbox">Sandbox</a></li>
<li style="margin-top: .5rem;"><wa-switch id="theme-toggle">Dark mode</wa-switch></li>
<script type="module">
// Temporary dark toggle
const toggle = document.getElementById('theme-toggle');
toggle.checked = document.documentElement.classList.contains('wa-theme-default-dark');
toggle.addEventListener('wa-change', () => {
document.documentElement.classList.toggle('wa-theme-default-dark');
localStorage.setItem('theme', toggle.checked ? 'dark' : 'light');
});
</script>
</ul>
{# Resources #}
<h2>Resources</h2>
<ul>
<li><a href="https://github.com/shoelace-style/shoelace/discussions">Help &amp; Support</a></li>
<li><a href="/docs/resources/community">Community</a></li>
<li><a href="/docs/resources/accessibility">Accessibility</a></li>
<li><a href="/docs/resources/contributing">Contributing</a></li>
<li><a href="/docs/resources/changelog">Changelog</a></li>
</ul>
{# Components #}
<h2>Components</h2>
<ul>
<li>
<a href="/docs/components/animated-image">Animated Image</a>
</li>
<li>
<a href="/docs/components/animation">Animation</a>
</li>
<li>
<a href="/docs/components/avatar">Avatar</a>
</li>
<li>
<a href="/docs/components/badge">Badge</a>
</li>
<li>
<a href="/docs/components/breadcrumb">Breadcrumb</a>
<h2>Getting Started</h2>
<ul>
<li>
<a href="/docs/components/breadcrumb-item">Breadcrumb Item</a>
</li>
<li><a href="/">Home</a></li>
<li><a href="/getting-started/installation">Installation</a></li>
<li><a href="/getting-started/usage">Usage</a></li>
<li><a href="/getting-started/themes">Themes</a></li>
<li><a href="/getting-started/customizing">Customizing</a></li>
<li><a href="/getting-started/form-controls">Form Controls</a></li>
<li><a href="/getting-started/localization">Localization</a></li>
</ul>
</li>
<li>
<a href="/docs/components/button">Button</a>
</li>
<li>
<a href="/docs/components/button-group">Button Group</a>
</li>
<li>
<a href="/docs/components/callout">Callout</a>
</li>
<li>
<a href="/docs/components/card">Card</a>
</li>
<li>
<a href="/docs/components/carousel">Carousel</a>
<h2>Frameworks</h2>
<ul>
<li>
<a href="/docs/components/carousel-item">Carousel Item</a>
</li>
<li><a href="/frameworks/react">React</a></li>
<li><a href="/frameworks/vue">Vue</a></li>
<li><a href="/frameworks/angular">Angular</a></li>
</ul>
</li>
<li>
<a href="/docs/components/checkbox">Checkbox</a>
</li>
<li>
<a href="/docs/components/color-picker">Color Picker</a>
</li>
<li>
<a href="/docs/components/copy-button">Copy Button</a>
</li>
<li>
<a href="/docs/components/details">Details</a>
</li>
<li>
<a href="/docs/components/dialog">Dialog</a>
</li>
<li>
<a href="/docs/components/divider">Divider</a>
</li>
<li>
<a href="/docs/components/drawer">Drawer</a>
</li>
<li>
<a href="/docs/components/dropdown">Dropdown</a>
</li>
<li>
<a href="/docs/components/format-bytes">Format Bytes</a>
</li>
<li>
<a href="/docs/components/format-date">Format Date</a>
</li>
<li>
<a href="/docs/components/format-number">Format Number</a>
</li>
<li>
<a href="/docs/components/icon">Icon</a>
</li>
<li>
<a href="/docs/components/icon-button">Icon Button</a>
</li>
<li>
<a href="/docs/components/image-comparer">Image Comparer</a>
</li>
<li>
<a href="/docs/components/include">Include</a>
</li>
<li>
<a href="/docs/components/input">Input</a>
</li>
<li>
<a href="/docs/components/menu">Menu</a>
<h2>Resources</h2>
<ul>
<li>
<a href="/docs/components/menu-item">Menu Item</a>
</li>
<li>
<a href="/docs/components/menu-label">Menu Label</a>
</li>
<li><a href="/resources/community">Community</a></li>
<li><a href="https://github.com/shoelace-style/shoelace/discussions">Help &amp; Support</a></li>
<li><a href="/resources/accessibility">Accessibility</a></li>
<li><a href="/resources/contributing">Contributing</a></li>
<li><a href="/resources/changelog">Changelog</a></li>
</ul>
</li>
<li>
<a href="/docs/components/mutation-observer">Mutation Observer</a>
</li>
<li>
<a href="/docs/components/option">Option</a>
</li>
<li>
<a href="/docs/components/page">Page</a>
</li>
<li>
<a href="/docs/components/popup">Popup</a>
</li>
<li>
<a href="/docs/components/progress-bar">Progress Bar</a>
</li>
<li>
<a href="/docs/components/progress-ring">Progress Ring</a>
</li>
<li>
<a href="/docs/components/qr-code">QR Code</a>
</li>
<li>
<a href="/docs/components/radio-group">Radio Group</a>
<h2>Components</h2>
<ul>
<li>
<a href="/docs/components/radio">Radio</a>
</li>
<li>
<a href="/docs/components/radio-button">Radio Button</a>
</li>
{% for component in meta.components %}
<li>
<a href="/components/{{ component.tagName | removeSlPrefix }}">
{{ component.name | classNameToComponentName }}
</a>
</li>
{% endfor %}
</ul>
</li>
<li>
<a href="/docs/components/range">Range</a>
</li>
<li>
<a href="/docs/components/rating">Rating</a>
</li>
<li>
<a href="/docs/components/relative-time">Relative Time</a>
</li>
<li>
<a href="/docs/components/resize-observer">Resize Observer</a>
</li>
<li>
<a href="/docs/components/select">Select</a>
</li>
<li>
<a href="/docs/components/skeleton">Skeleton</a>
</li>
<li>
<a href="/docs/components/spinner">Spinner</a>
</li>
<li>
<a href="/docs/components/split-panel">Split Panel</a>
</li>
<li>
<a href="/docs/components/switch">Switch</a>
</li>
<li>
<a href="/docs/components/tab-group">Tab Group</a>
<h2>Design Tokens</h2>
<ul>
<li>
<a href="/docs/components/tab">Tab</a>
</li>
<li>
<a href="/docs/components/tab-panel">Tab Panel</a>
</li>
<li><a href="/tokens/typography">Typography</a></li>
<li><a href="/tokens/color">Color</a></li>
<li><a href="/tokens/spacing">Spacing</a></li>
<li><a href="/tokens/elevation">Elevation</a></li>
<li><a href="/tokens/border-radius">Border Radius</a></li>
<li><a href="/tokens/transition">Transition</a></li>
<li><a href="/tokens/z-index">Z-index</a></li>
<li><a href="/tokens/more">More Tokens</a></li>
</ul>
</li>
<li>
<a href="/docs/components/tag">Tag</a>
</li>
<li>
<a href="/docs/components/textarea">Textarea</a>
</li>
<li>
<a href="/docs/components/tooltip">Tooltip</a>
</li>
<li>
<a href="/docs/components/tree">Tree</a>
<h2>Tutorials</h2>
<ul>
<li>
<a href="/docs/components/tree-item">Tree Item</a>
</li>
<li><a href="/tutorials/integrating-with-laravel">Integrating with Laravel</a></li>
<li><a href="/tutorials/integrating-with-nextjs">Integrating with NextJS</a></li>
<li><a href="/tutorials/integrating-with-rails">Integrating with Rails</a></li>
</ul>
</li>
<li>
<a href="/docs/components/visually-hidden">Visually Hidden</a>
</li>
</ul>

View File

@@ -1,298 +0,0 @@
{% set hasSidebar = true %}
{% set hasOutline = true %}
{% set component = getComponent('wa-' + page.fileSlug) %}
{% set description = component.summary %}
{% extends '../_includes/base.njk' %}
{# Component header #}
{% block beforeContent %}
<h1 class="title">{{ title }}</h1>
<div class="component-info">
<code class="component-tag">&lt;{{ component.tagName }}&gt;</code>
<wa-badge variant="neutral">Since {{ component.since }}</wa-badge>
<wa-badge
{% if component.status == 'stable' %}variant="brand"{% endif %}
{% if component.status == 'experimental' %}variant="warning"{% endif %}
>
{{ component.status }}
</wa-badge>
</div>
<p class="component-summary">
{{ component.summary }}
</p>
{% endblock %}
{# Content #}
{% block content %}
{{ content | safe }}
{% endblock %}
{# Component API #}
{% block afterContent %}
{# Slots #}
{% if component.slots.length %}
<h2>Slots</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for slot in component.slots %}
<tr>
<td class="table-name">
{% if slot.name %}
<code>{{ slot.name }}</code>
{% else %}
(default)
{% endif %}
</td>
<td class="table-description">{{ slot.description | inlineMarkdown | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# Properties #}
{% if component.properties.length %}
<h2>Properties</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-attribute">Attribute</th>
<th class="table-description">Description</th>
<th class="table-reflects">Reflects</th>
<th class="table-type">Type</th>
<th class="table-default">Default</th>
</tr>
</thead>
<tbody>
{% for prop in component.properties %}
<tr>
<td class="table-name">
<code>{{ prop.name }}</code>
</td>
<td class="table-attribute">
{% if prop.attribute %}
<code>{{ prop.attribute }}</code>
{% endif %}
</td>
<td class="table-description">
{{ prop.description | inlineMarkdown | safe }}
</td>
<td class="table-checkmark">
{% if prop.reflects %}
<wa-icon name="check"></wa-icon>
{% endif %}
</td>
<td class="table-type">
{% if prop.type.text %}
<code>{{ prop.type.text | trimPipes | inlineMarkdown | safe }}</code>
{% endif %}
</td>
<td class="table-default">
{% if prop.default %}
<code>{{ prop.default | inlineMarkdown | safe }}</code>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# Methods #}
{% if component.methods.length %}
<h2>Methods</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-arguments">Arguments</th>
</tr>
</thead>
<tbody>
{% for method in component.methods %}
<tr>
<td class="table-name"><code>{{ method.name }}()</code></td>
<td class="table-description">{{ method.description | inlineMarkdown | safe }}</td>
<td class="table-arguments">
{% if method.parameters.length %}
<code>
{% for param in method.parameters %}
{{ param.name }}: {{ param.type.text | trimPipes }}{% if not loop.last %},{% endif %}
{% endfor %}
</code>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# States #}
{% if component.states.length %}
<h2>States</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-selector">CSS selector</th>
</tr>
</thead>
<tbody>
{% for state in component.states %}
<tr>
<td class="table-name"><code>{{ state.name }}</code></td>
<td class="table-description">{{ state.description | inlineMarkdown | safe }}</td>
<td class="table-selector"><code>[data-state-{{ state.name }}]</code></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# Events #}
{% if component.events.length %}
<h2>Events</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for event in component.events %}
{% if event.name %}
<tr>
<td class="table-name"><code>{{ event.name }}</code></td>
<td class="table-description">{{ event.description | inlineMarkdown | safe }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# Custom Properties #}
{% if component.cssProperties.length %}
<h2>CSS custom properties</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
{% for cssProperty in component.cssProperties %}
<tr>
<td class="table-name"><code>{{ cssProperty.name }}</code></td>
<td class="table-description">{{ cssProperty.description | inlineMarkdown | safe }}</td>
<td class="table-default">
{% if cssProperty.default %}
<code>{{ cssProperty.default }}</code>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# CSS Parts #}
{% if component.cssParts.length %}
<h2>CSS parts</h2>
<div class="table-scroll">
<table class="component-table">
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-selector">CSS selector</th>
</tr>
</thead>
<tbody>
{% for cssPart in component.cssParts %}
<tr>
<td class="table-name"><code>{{ cssPart.name }}</code></td>
<td class="table-description">{{ cssPart.description | inlineMarkdown | safe }}</td>
<td class="table-selector"><code>::part({{ cssPart.name }})</code></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{# Dependencies #}
{% if component.dependencies.length %}
<h2>Dependencies</h2>
<p>
This component automatically imports the following elements. Subdependencies, if any exist, will also be included in this list.
</p>
<ul class="dependency-list">
{% for dependency in component.dependencies %}
<li><a href="/docs/components/{{ dependency | stripPrefix }}"><code>&lt;{{ dependency }}&gt;</code></a></li>
{% endfor %}
</ul>
{% endif %}
{# Importing #}
<h2>Importing</h2>
<p>
The <a href="/docs/#autoloading">autoloader</a> is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
</p>
<wa-tab-group label="How would you like to import this component?">
<wa-tab slot="nav" panel="cdn">CDN</wa-tab>
<wa-tab slot="nav" panel="npm">npm</wa-tab>
<wa-tab slot="nav" panel="react">React</wa-tab>
<wa-tab-panel name="cdn">
<p>
To manually import this component from the CDN, use the following code.
</p>
<pre><code class="language-js">import '{% cdnUrl component.path %}';</code></pre>
</wa-tab-panel>
<wa-tab-panel name="npm">
<p>
To manually import this component from npm, use the following code.
</p>
<pre><code class="language-js">import '@shoelace-style/webawesome/{{ component.path }}';</code></pre>
</wa-tab-panel>
<wa-tab-panel name="react">
<p>
To manually import this component from React, use the following code.
</p>
<pre><code class="language-js">import '@shoelace-style/webawesome/react/{{ component.tagName | stripPrefix }}';</code></pre>
</wa-tab-panel>
</wa-tab-group>
{% endblock %}

View File

@@ -1,5 +0,0 @@
{% set hasSidebar = true %}
{% set hasOutline = true %}
{% set section = 'docs' %}
{% extends "../_includes/base.njk" %}

View File

@@ -1,4 +0,0 @@
{% set hasSidebar = true %}
{% set hasOutline = false %}
{% extends "../_includes/base.njk" %}

View File

@@ -0,0 +1,35 @@
function normalizePathname(pathname) {
// Remove /index.html
if (pathname.endsWith('/index.html')) {
pathname = pathname.replace(/\/index\.html/, '');
}
// Remove trailing slashes
return pathname.replace(/\/$/, '');
}
/**
* Adds a class name to links that are currently active.
*/
module.exports = function (doc, options) {
options = {
className: 'active-link', // the class to add to active links
pathname: undefined, // the current pathname to compare
within: 'body', // element containing the target links
...options
};
const within = doc.querySelector(options.within);
if (!within) {
return doc;
}
within.querySelectorAll('a').forEach(link => {
if (normalizePathname(options.pathname) === normalizePathname(link.pathname)) {
link.classList.add(options.className);
}
});
return doc;
};

View File

@@ -0,0 +1,64 @@
const { createSlug } = require('./strings.cjs');
/**
* Turns headings into clickable, deep linkable anchors. The provided doc should be a document object provided by JSDOM.
* The same document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc, options) {
options = {
levels: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'], // the headings to convert
className: 'anchor-heading', // the class name to add
within: 'body', // the element containing the target headings
...options
};
const within = doc.querySelector(options.within);
if (!within) {
return doc;
}
within.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(heading => {
const hasAnchor = heading.querySelector('a');
const anchor = doc.createElement('a');
let id = heading.textContent ?? '';
let suffix = 0;
// Skip heading levels we don't care about
if (!options.levels?.includes(heading.tagName.toLowerCase())) {
return;
}
// Convert dots to underscores
id = id.replace(/\./g, '_');
// Turn it into a slug
id = createSlug(id);
// Make sure it starts with a letter
if (!/^[a-z]/i.test(id)) {
id = `id_${id}`;
}
// Make sure the id is unique
const originalId = id;
while (doc.getElementById(id) !== null) {
id = `${originalId}-${++suffix}`;
}
if (hasAnchor || !id) return;
heading.setAttribute('id', id);
anchor.setAttribute('href', `#${encodeURIComponent(id)}`);
anchor.setAttribute('aria-label', `Direct link to "${heading.textContent}"`);
if (options.className) {
heading.classList.add(options.className);
}
// Append the anchor
heading.append(anchor);
});
return doc;
};

View File

@@ -1,23 +1,23 @@
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
import { readFileSync } from 'fs';
const customElementsManifest = require('../../dist/custom-elements.json');
const __dirname = dirname(fileURLToPath(import.meta.url));
//
// Export it here so we can import it elsewhere and use the same version
//
module.exports.customElementsManifest = customElementsManifest;
const manifest = JSON.parse(readFileSync(resolve(__dirname, '../../dist/custom-elements.json'), 'utf-8'));
/**
* @returns Fetches components from custom-elements.json and returns them in more sane format.
*/
export function getComponents() {
const components = [];
//
// Gets all components from custom-elements.json and returns them in a more documentation-friendly format.
//
module.exports.getAllComponents = function () {
const allComponents = [];
manifest.modules?.forEach(module => {
customElementsManifest.modules?.forEach(module => {
module.declarations?.forEach(declaration => {
if (declaration.customElement) {
// Generate the dist path based on the src path and attach it to the component
declaration.path = module.path.replace(/^src\//, 'dist/').replace(/\.ts$/, '.js');
// Remove private members and those that lack a description
// Remove members that are private or don't have a description
const members = declaration.members?.filter(member => member.description && member.privacy !== 'private');
const methods = members?.filter(prop => prop.kind === 'method' && prop.privacy !== 'private');
const properties = members?.filter(prop => {
@@ -29,7 +29,7 @@ export function getComponents() {
return prop.kind === 'field' && prop.privacy !== 'private';
});
components.push({
allComponents.push({
...declaration,
methods,
properties
@@ -39,12 +39,12 @@ export function getComponents() {
});
// Build dependency graphs
components.forEach(component => {
allComponents.forEach(component => {
const dependencies = [];
// Recursively fetch sub-dependencies
function getDependencies(tag) {
const cmp = components.find(c => c.tagName === tag);
const cmp = allComponents.find(c => c.tagName === tag);
if (!cmp || !Array.isArray(component.dependencies)) {
return;
}
@@ -63,9 +63,9 @@ export function getComponents() {
});
// Sort by name
return components.sort((a, b) => {
return allComponents.sort((a, b) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
}
};

View File

@@ -0,0 +1,138 @@
let count = 1;
function escapeHtml(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
/**
* Turns code fields with the :preview suffix into interactive code previews.
*/
module.exports = function (doc, options) {
options = {
within: 'body', // the element containing the code fields to convert
...options
};
const within = doc.querySelector(options.within);
if (!within) {
return doc;
}
within.querySelectorAll('[class*=":preview"]').forEach(code => {
const pre = code.closest('pre');
if (!pre) {
return;
}
const adjacentPre = pre.nextElementSibling?.tagName.toLowerCase() === 'pre' ? pre.nextElementSibling : null;
const reactCode = adjacentPre?.querySelector('code[class$="react"]');
const sourceGroupId = `code-preview-source-group-${count}`;
const isExpanded = code.getAttribute('class').includes(':expanded');
const noCodePen = code.getAttribute('class').includes(':no-codepen');
count++;
const htmlButton = `
<button type="button"
title="Show HTML code"
class="code-preview__button code-preview__button--html"
>
HTML
</button>
`;
const reactButton = `
<button type="button" title="Show React code" class="code-preview__button code-preview__button--react">
React
</button>
`;
const codePenButton = `
<button type="button" class="code-preview__button code-preview__button--codepen" title="Edit on CodePen">
<svg
width="138"
height="26"
viewBox="0 0 138 26"
fill="none"
stroke="currentColor"
stroke-width="2.3"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M80 6h-9v14h9 M114 6h-9 v14h9 M111 13h-6 M77 13h-6 M122 20V6l11 14V6 M22 16.7L33 24l11-7.3V9.3L33 2L22 9.3V16.7z M44 16.7L33 9.3l-11 7.4 M22 9.3l11 7.3 l11-7.3 M33 2v7.3 M33 16.7V24 M88 14h6c2.2 0 4-1.8 4-4s-1.8-4-4-4h-6v14 M15 8c-1.3-1.3-3-2-5-2c-4 0-7 3-7 7s3 7 7 7 c2 0 3.7-0.8 5-2 M64 13c0 4-3 7-7 7h-5V6h5C61 6 64 9 64 13z" />
</svg>
</button>
`;
const codePreview = `
<div class="code-preview ${isExpanded ? 'code-preview--expanded' : ''}">
<div class="code-preview__preview">
${code.textContent}
<div class="code-preview__resizer">
<sl-icon name="grip-vertical"></sl-icon>
</div>
</div>
<div class="code-preview__source-group" id="${sourceGroupId}">
<div class="code-preview__source code-preview__source--html" ${reactCode ? 'data-flavor="html"' : ''}>
<pre><code class="language-html">${escapeHtml(code.textContent)}</code></pre>
</div>
${
reactCode
? `
<div class="code-preview__source code-preview__source--react" data-flavor="react">
<pre><code class="language-jsx">${escapeHtml(reactCode.textContent)}</code></pre>
</div>
`
: ''
}
</div>
<div class="code-preview__buttons">
<button
type="button"
class="code-preview__button code-preview__toggle"
aria-expanded="${isExpanded ? 'true' : 'false'}"
aria-controls="${sourceGroupId}"
>
Source
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
${reactCode ? ` ${htmlButton} ${reactButton} ` : ''}
${noCodePen ? '' : codePenButton}
</div>
</div>
`;
pre.insertAdjacentHTML('afterend', codePreview);
pre.remove();
if (adjacentPre) {
adjacentPre.remove();
}
});
// Wrap code preview scripts in anonymous functions so they don't run in the global scope
doc.querySelectorAll('.code-preview__preview script').forEach(script => {
if (script.type === 'module') {
// Modules are already scoped
script.textContent = script.innerHTML;
} else {
// Wrap non-modules in an anonymous function so they don't run in the global scope
script.textContent = `(() => { ${script.innerHTML} })();`;
}
});
return doc;
};

View File

@@ -0,0 +1,26 @@
/**
* Adds copy code buttons to code fields. The provided doc should be a document object provided by JSDOM. The same
* document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc) {
doc.querySelectorAll('pre > code').forEach(code => {
const pre = code.closest('pre');
const button = doc.createElement('button');
button.setAttribute('type', 'button');
button.classList.add('copy-code-button');
button.setAttribute('aria-label', 'Copy');
button.innerHTML = `
<svg class="copy-code-button__copy-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-files" viewBox="0 0 16 16" part="svg">
<path d="M13 0H6a2 2 0 0 0-2 2 2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2 2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 13V4a2 2 0 0 0-2-2H5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zM3 4a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4z"></path>
</svg>
<svg class="copy-code-button__copied-icon" style="display: none;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-lg" viewBox="0 0 16 16" part="svg">
<path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425a.247.247 0 0 1 .02-.022Z"></path>
</svg>
`;
pre.append(button);
});
return doc;
};

View File

@@ -0,0 +1,41 @@
const { isExternalLink } = require('./strings.cjs');
/**
* Transforms external links to make them safer and optionally add a target. The provided doc should be a document
* object provided by JSDOM. The same document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc, options) {
options = {
className: 'external-link', // the class name to add to links
noopener: true, // sets rel="noopener"
noreferrer: true, // sets rel="noreferrer"
ignore: () => false, // callback function to filter links that should be ignored
within: 'body', // element that contains the target links
target: '', // sets the target attribute
...options
};
const within = doc.querySelector(options.within);
if (within) {
within.querySelectorAll('a').forEach(link => {
if (isExternalLink(link) && !options.ignore(link)) {
link.classList.add(options.className);
const rel = [];
if (options.noopener) rel.push('noopener');
if (options.noreferrer) rel.push('noreferrer');
if (rel.length) {
link.setAttribute('rel', rel.join(' '));
}
if (options.target) {
link.setAttribute('target', options.target);
}
}
});
}
return doc;
};

View File

@@ -0,0 +1,63 @@
const Prism = require('prismjs');
const PrismLoader = require('prismjs/components/index.js');
PrismLoader('diff');
PrismLoader.silent = true;
/** Highlights a code string. */
function highlight(code, language) {
const alias = language.replace(/^diff-/, '');
const isDiff = /^diff-/i.test(language);
// Auto-load the target language
if (!Prism.languages[alias]) {
PrismLoader(alias);
if (!Prism.languages[alias]) {
throw new Error(`Unsupported language for code highlighting: "${language}"`);
}
}
// Register diff-* languages to use the diff grammar
if (isDiff) {
Prism.languages[language] = Prism.languages.diff;
}
return Prism.highlight(code, Prism.languages[language], language);
}
/**
* Highlights all code fields that have a language parameter. If the language has a colon in its name, the first chunk
* will be the language used and additional chunks will be applied as classes to the `<pre>`. For example, a code field
* tagged with "html:preview" will be rendered as `<pre class="language-html preview">`.
*
* The provided doc should be a document object provided by JSDOM. The same document will be returned with the
* appropriate DOM manipulations.
*/
module.exports = function (doc) {
doc.querySelectorAll('pre > code[class]').forEach(code => {
// Look for class="language-*" and split colons into separate classes
code.classList.forEach(className => {
if (className.startsWith('language-')) {
//
// We use certain suffixes to indicate code previews, expanded states, etc. The class might look something like
// this:
//
// class="language-html:preview:expanded"
//
// The language will always come first, so we need to drop the "language-" prefix and everything after the first
// color to get the highlighter language.
//
const language = className.replace(/^language-/, '').split(':')[0];
try {
code.innerHTML = highlight(code.textContent ?? '', language);
} catch (err) {
// Language not found, skip it
}
}
});
});
return doc;
};

View File

@@ -1,14 +1,11 @@
import MarkdownIt from 'markdown-it';
import markdownItAttrs from 'markdown-it-attrs';
import markdownItContainer from 'markdown-it-container';
import markdownItIns from 'markdown-it-ins';
import markdownItKbd from 'markdown-it-kbd';
import markdownItMark from 'markdown-it-mark';
const MarkdownIt = require('markdown-it');
const markdownItContainer = require('markdown-it-container');
const markdownItIns = require('markdown-it-ins');
const markdownItKbd = require('markdown-it-kbd');
const markdownItMark = require('markdown-it-mark');
const markdownItReplaceIt = require('markdown-it-replace-it');
/**
* A custom Markdown It instance with added features.
*/
export const markdown = MarkdownIt({
const markdown = MarkdownIt({
html: true,
xhtmlOut: false,
breaks: false,
@@ -17,27 +14,26 @@ export const markdown = MarkdownIt({
typographer: false
});
// Third-party plugins
markdown.use(markdownItContainer);
markdown.use(markdownItIns);
markdown.use(markdownItKbd);
markdown.use(markdownItMark);
markdown.use(markdownItReplaceIt);
['info', 'warning'].forEach(type => {
// Callouts
['tip', 'warning', 'danger'].forEach(type => {
markdown.use(markdownItContainer, type, {
render: function (tokens, idx) {
const variant = type === 'warning' ? 'warning' : 'info';
const icon = type === 'warning' ? 'triangle-exclamation' : 'circle-info';
if (tokens[idx].nesting === 1) {
return `
<div class="callout callout-${variant}">
<wa-icon class="callout-icon" name="${icon}"></wa-icon>
<div class="callout-content">
`;
return `<div role="alert" class="callout callout--${type}">`;
}
return '</div></div>\n';
return '</div>\n';
}
});
});
// Asides
markdown.use(markdownItContainer, 'aside', {
render: function (tokens, idx) {
if (tokens[idx].nesting === 1) {
@@ -47,6 +43,7 @@ markdown.use(markdownItContainer, 'aside', {
}
});
// Details
markdown.use(markdownItContainer, 'details', {
validate: params => params.trim().match(/^details\s+(.*)$/),
render: (tokens, idx) => {
@@ -58,6 +55,13 @@ markdown.use(markdownItContainer, 'details', {
}
});
markdown.use(markdownItAttrs, {
allowedAttributes: ['id', 'class', 'data']
// Replace [#1234] with a link to GitHub issues
markdownItReplaceIt.replacements.push({
name: 'github-issues',
re: /\[#([0-9]+)\]/gs,
sub: '<a href="https://github.com/shoelace-style/shoelace/issues/$1">#$1</a>',
html: true,
default: true
});
module.exports = markdown;

View File

@@ -0,0 +1,26 @@
const { format } = require('prettier');
/** Formats markup using prettier. */
module.exports = function (content, options) {
options = {
arrowParens: 'avoid',
bracketSpacing: true,
htmlWhitespaceSensitivity: 'css',
insertPragma: false,
bracketSameLine: false,
jsxSingleQuote: false,
parser: 'html',
printWidth: 120,
proseWrap: 'preserve',
quoteProps: 'as-needed',
requirePragma: false,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'none',
useTabs: false,
...options
};
return format(content, options);
};

View File

@@ -0,0 +1,19 @@
/**
* @typedef {object} Replacement
* @property {string | RegExp} pattern
* @property {string} replacement
*/
/**
* @typedef {Array<Replacement>} Replacements
*/
/**
* @param {Document} content
* @param {Replacements} replacements
*/
module.exports = function (content, replacements) {
replacements.forEach(replacement => {
content.body.innerHTML = content.body.innerHTML.replaceAll(replacement.pattern, replacement.replacement);
});
};

View File

@@ -0,0 +1,21 @@
/**
* Turns headings into clickable, deep linkable anchors. The provided doc should be a document object provided by JSDOM.
* The same document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc, options) {
const tables = [...doc.querySelectorAll('table')];
options = {
className: 'table-scroll', // the class name to add to the table's container
...options
};
tables.forEach(table => {
const div = doc.createElement('div');
div.classList.add(options.className);
table.insertAdjacentElement('beforebegin', div);
div.append(table);
});
return doc;
};

View File

@@ -0,0 +1,16 @@
const slugify = require('slugify');
/** Creates a slug from an arbitrary string of text. */
module.exports.createSlug = function (text) {
return slugify(String(text), {
remove: /[^\w|\s]/g,
lower: true
});
};
/** Determines whether or not a link is external. */
module.exports.isExternalLink = function (link) {
// We use the "internal" hostname when initializing JSDOM so we know that those are local links
if (!link.hostname || link.hostname === 'internal') return false;
return true;
};

View File

@@ -0,0 +1,42 @@
/**
* Generates an in-page table of contents based on headings.
*/
module.exports = function (doc, options) {
options = {
levels: ['h2'], // headings to include (they must have an id)
container: 'nav', // the container to append links to
listItem: true, // if true, links will be wrapped in <li>
within: 'body', // the element containing the headings to summarize
...options
};
const container = doc.querySelector(options.container);
const within = doc.querySelector(options.within);
const headingSelector = options.levels.map(h => `${h}[id]`).join(', ');
if (!container || !within) {
return doc;
}
within.querySelectorAll(headingSelector).forEach(heading => {
const listItem = doc.createElement('li');
const link = doc.createElement('a');
const level = heading.tagName.slice(1);
link.href = `#${heading.id}`;
link.textContent = heading.textContent;
if (options.listItem) {
// List item + link
listItem.setAttribute('data-level', level);
listItem.append(link);
container.append(listItem);
} else {
// Link only
link.setAttribute('data-level', level);
container.append(link);
}
});
return doc;
};

View File

@@ -0,0 +1,23 @@
const smartquotes = require('smartquotes');
smartquotes.replacements.push([/---/g, '\u2014']); // em dash
smartquotes.replacements.push([/--/g, '\u2013']); // en dash
smartquotes.replacements.push([/\.\.\./g, '\u2026']); // ellipsis
smartquotes.replacements.push([/\(c\)/gi, '\u00A9']); // copyright
smartquotes.replacements.push([/\(r\)/gi, '\u00AE']); // registered trademark
smartquotes.replacements.push([/\?!/g, '\u2048']); // ?!
smartquotes.replacements.push([/!!/g, '\u203C']); // !!
smartquotes.replacements.push([/\?\?/g, '\u2047']); // ??
smartquotes.replacements.push([/([0-9]\s?)-(\s?[0-9])/g, '$1\u2013$2']); // number ranges use en dash
/**
* Improves typography by adding smart quotes and similar corrections within the specified element(s).
*
* The provided doc should be a document object provided by JSDOM. The same document will be returned with the
* appropriate DOM manipulations.
*/
module.exports = function (doc, selector = 'body') {
const elements = [...doc.querySelectorAll(selector)];
elements.forEach(el => smartquotes.element(el));
return doc;
};

View File

@@ -1,78 +0,0 @@
import { parse } from 'node-html-parser';
import { v4 as uuid } from 'uuid';
import slugify from 'slugify';
function createId(text) {
let slug = slugify(String(text), {
remove: /[^\w|\s]/g,
lower: true
});
// ids must start with a letter
if (!/^[a-z]/i.test(slug)) {
slug = `wa_${slug}`;
}
return slug;
}
/**
* Eleventy plugin to add anchors to headings to content.
*/
export function anchorHeadingsPlugin(options = {}) {
options = {
container: 'body',
headingSelector: 'h2, h3, h4, h5, h6',
anchorLabel: 'Jump to heading',
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('anchor-headings', content => {
const doc = parse(content);
const container = doc.querySelector(options.container);
if (!container) {
return content;
}
// Look for headings
container.querySelectorAll(options.headingSelector).forEach(heading => {
const hasAnchor = heading.querySelector('a');
const clone = parse(heading.outerHTML);
// Create a clone of the heading so we can remove [data-no-anchor] elements from the text content
clone.querySelectorAll('[data-no-anchor]').forEach(el => el.remove());
const slug = createId(clone.textContent ?? '') ?? uuid().slice(-12);
let id = slug;
let suffix = 0;
// Make sure the slug is unique in the document
while (doc.getElementById(id) !== null) {
id = `${slug}-${++suffix}`;
}
if (hasAnchor || !id) {
return;
}
// Create the anchor
const anchor = parse(`
<a href="#${encodeURIComponent(id)}">
<span class="wa-visually-hidden"></span>
<span aria-hidden="true">#</span>
</a>
`);
anchor.querySelector('.wa-visually-hidden').textContent = options.anchorLabel;
// Update the heading
heading.setAttribute('id', id);
heading.classList.add('anchor-heading');
heading.appendChild(anchor);
});
return doc.toString();
});
};
}

View File

@@ -1,82 +0,0 @@
import { parse } from 'node-html-parser';
import { v4 as uuid } from 'uuid';
/**
* Eleventy plugin to turn `<code class="example">` blocks into live examples.
*/
export function codeExamplesPlugin(options = {}) {
options = {
container: 'body',
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('code-examples', content => {
const doc = parse(content, { blockTextElements: { code: true } });
const container = doc.querySelector(options.container);
if (!container) {
return content;
}
// Look for external links
container.querySelectorAll('code.example').forEach(code => {
const pre = code.closest('pre');
const hasButtons = !code.classList.contains('no-buttons');
const isOpen = code.classList.contains('open') || !hasButtons;
const noEdit = code.classList.contains('no-edit');
const id = `code-example-${uuid().slice(-12)}`;
let preview = pre.textContent;
// Run preview scripts as modules to prevent collisions
const root = parse(preview, { blockTextElements: { script: true } });
root.querySelectorAll('script').forEach(script => script.setAttribute('type', 'module'));
preview = root.toString();
const codeExample = parse(`
<div class="code-example ${isOpen ? 'open' : ''}">
<div class="code-example-preview">
${preview}
</div>
<div class="code-example-source" id="${id}">
${pre.outerHTML}
</div>
${
hasButtons
? `
<div class="code-example-buttons">
<button
class="code-example-toggle"
type="button"
aria-expanded="${isOpen ? 'true' : 'false'}"
aria-controls="${id}"
>
Code
<wa-icon name="chevron-down"></wa-icon>
</button>
${
noEdit
? ''
: `
<button class="code-example-pen" type="button">
<wa-icon name="pen-to-square"></wa-icon>
Edit
</button>
`
}
`
: ''
}
</div>
</div>
`);
pre.replaceWith(codeExample);
});
return doc.toString();
});
};
}

View File

@@ -1,32 +0,0 @@
import { parse } from 'node-html-parser';
/**
* Eleventy plugin to add copy buttons to code blocks.
*/
export function copyCodePlugin(options = {}) {
options = {
container: 'body',
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('copy-code', content => {
const doc = parse(content, { blockTextElements: { code: true } });
const container = doc.querySelector(options.container);
if (!container) {
return content;
}
// Look for code blocks
container.querySelectorAll('pre > code').forEach(code => {
const pre = code.closest('pre');
// Add a copy button (we set the copy data at runtime to reduce page bloat)
pre.innerHTML = `<wa-copy-button class="copy-button" hoist></wa-copy-button>` + pre.innerHTML;
});
return doc.toString();
});
};
}

View File

@@ -1,53 +0,0 @@
import { parse } from 'node-html-parser';
function normalize(pathname) {
pathname = pathname.trim();
// Must start with a slash
if (!pathname.startsWith('/')) {
pathname = `/${pathname}`;
}
// Must not end in a slash
if (pathname.endsWith('/')) {
pathname = pathname.slice(0, -1);
}
// Convert /index.html to /
if (pathname.endsWith('/index.html')) {
pathname = pathname.slice(0, -10);
}
return pathname;
}
/**
* Eleventy plugin to decorate current links with a custom class.
*/
export function currentLink(options = {}) {
options = {
container: 'body',
className: 'current',
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('current-link', function (content) {
const doc = parse(content);
const container = doc.querySelector(options.container);
if (!container) {
return content;
}
// Compare the href attribute to 11ty's page URL
container.querySelectorAll('a[href]').forEach(a => {
if (normalize(a.getAttribute('href')) === normalize(this.page.url)) {
a.classList.add(options.className);
}
});
return doc.toString();
});
};
}

View File

@@ -1,32 +0,0 @@
import { format } from 'prettier';
import defaultOptions from '../../prettier.config.js';
/**
* Formats a string of code using Prettier.
*
* @param {string} code - The code to format.
* @param {*} options - Prettier options. Defaults are taken from the project's root config. See this page for more
* info: https://prettier.io/docs/en/options.html
*/
export async function formatCode(string, options) {
return await format(string, {
...defaultOptions,
...options
});
}
/**
* Eleventy plugin to format page HTML using Prettier.
*/
export function formatCodePlugin(options = {}) {
options = {
parser: 'html',
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('format-code', content => {
return formatCode(content, options);
});
};
}

View File

@@ -1,72 +0,0 @@
/* eslint sort-imports-es6-autofix/sort-imports-es6: 0 */
import { parse } from 'node-html-parser';
import Prism from 'prismjs';
import 'prismjs/plugins/custom-class/prism-custom-class.js';
import PrismLoader from 'prismjs/components/index.js';
PrismLoader('diff');
PrismLoader.silent = true;
Prism.plugins.customClass.prefix('code-');
/**
* Highlights a string of code using the specified language.
*
* @param {string} code - The code to highlight.
* @param {string} language - The language the code is written in. For available languages, refer to this page:
* https://prismjs.com/#supported-languages
*/
export function highlightCode(code, language = 'plain') {
const alias = language.replace(/^diff-/, '');
const isDiff = /^diff-/i.test(language);
if (!Prism.languages[alias]) {
PrismLoader(alias);
if (!Prism.languages[alias]) {
throw new Error(`Unsupported language for code highlighting: "${language}"`);
}
}
if (isDiff) {
Prism.languages[language] = Prism.languages.diff;
}
return Prism.highlight(code, Prism.languages[language], language);
}
/**
* Eleventy plugin to highlight code blocks with the `language-*` attribute using Prism.js. Unlike most plugins, this
* works on the entire document — not just markdown content.
*/
export function highlightCodePlugin(options = {}) {
options = {
container: 'body',
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('highlight-code', content => {
const doc = parse(content, { blockTextElements: { code: true } });
const container = doc.querySelector(options.container);
if (!container) {
return content;
}
// Look for <code class="language-*"> and highlight each one
container.querySelectorAll('code[class*="language-"]').forEach(code => {
const langClass = [...code.classList.values()].find(val => val.startsWith('language-'));
const lang = langClass ? langClass.replace(/^language-/, '') : 'plain';
try {
code.innerHTML = highlightCode(code.textContent ?? '', lang);
} catch (err) {
if (!options.ignoreMissingLangs) {
throw new Error(err.message);
}
}
});
return doc.toString();
});
};
}

View File

@@ -1,69 +0,0 @@
import { parse } from 'node-html-parser';
/**
* Eleventy plugin to add an outline (table of contents) to the page. Headings must have an id, otherwise they won't be
* included in the outline. An unordered list containing links will be appended to the target element.
*
* If no headings are found for the outline, the `ifEmpty()` function will be called with a `node-html-parser` object as
* the first argument. This can be used to toggle classes or remove elements when the outline is empty.
*
* See the `node-html-parser` docs for more details: https://www.npmjs.com/package/node-html-parser
*/
export function outlinePlugin(options = {}) {
options = {
container: 'body',
target: '.outline',
selector: 'h2,h3',
ifEmpty: () => null,
...options
};
return function (eleventyConfig) {
eleventyConfig.addTransform('outline', content => {
const doc = parse(content);
const container = doc.querySelector(options.container);
const ul = parse('<ul></ul>');
let numLinks = 0;
if (!container) {
return content;
}
container.querySelectorAll(options.selector).forEach(heading => {
const id = heading.getAttribute('id');
const level = heading.tagName.slice(1);
const clone = parse(heading.outerHTML);
if (heading.closest('[data-no-outline]')) {
return;
}
// Create a clone of the heading so we can remove links and [data-no-outline] elements from the text content
clone.querySelectorAll('a').forEach(a => a.remove());
clone.querySelectorAll('[data-no-outline]').forEach(el => el.remove());
// Generate the link
const li = parse(`<li data-level="${level}"><a></a></li>`);
const a = li.querySelector('a');
a.setAttribute('href', `#${encodeURIComponent(id)}`);
a.textContent = clone.textContent.trim().replace(/#$/, '');
// Add it to the list
ul.firstChild.appendChild(li);
numLinks++;
});
if (numLinks > 0) {
// Append the list to all matching targets
doc.querySelectorAll(options.target).forEach(target => {
target.appendChild(parse(ul.outerHTML));
});
} else {
// Remove if empty
options.ifEmpty(doc);
}
return doc.toString();
});
};
}

View File

@@ -1,19 +0,0 @@
/**
* Eleventy plugin to replace arbitrary text in the page's HTML.
*
* @param replacement - The terms to replace and what to replace them with. This must be an object (or an array of
* objects) containing a `replace` key that's a string or RegExp and a `replaceWith` key that's a string.
*/
export function replaceTextPlugin(replacements = []) {
replacements = Array.isArray(replacements) ? replacements : [replacements];
return function (eleventyConfig) {
eleventyConfig.addTransform('replace-text', function (content) {
replacements.forEach(replacement => {
content = content.replace(replacement.replace, replacement.replaceWith);
});
return content;
});
};
}

View File

@@ -1,76 +0,0 @@
/* eslint-disable no-invalid-this */
import { dirname, join } from 'path';
import { mkdir, writeFile } from 'fs/promises';
import { parse } from 'node-html-parser';
import lunr from 'lunr';
function collapseWhitespace(string) {
return string.replace(/\s+/g, ' ');
}
/**
* Eleventy plugin to build a Lunr search index.
*/
export function searchPlugin(options = {}) {
options = {
filename: '',
selectorsToIgnore: [],
getTitle: doc => doc.querySelector('title')?.textContent ?? '',
getDescription: doc => doc.querySelector('meta[name="description"]')?.getAttribute('content') ?? '',
getHeadings: doc => [...doc.querySelectorAll('h1, h2, h3, h4, h5, h6')].map(heading => heading.textContent ?? ''),
getContent: doc => doc.querySelector('body')?.textContent ?? '',
...options
};
return function (eleventyConfig) {
const pagesToIndex = [];
eleventyConfig.addTransform('search', function (content) {
const doc = parse(content, {
blockTextElements: {
script: false,
noscript: false,
style: false,
pre: false,
code: false
}
});
// Remove content that shouldn't be searchable to reduce the index size
options.selectorsToIgnore.forEach(selector => {
doc.querySelectorAll(selector).forEach(el => el.remove());
});
pagesToIndex.push({
title: collapseWhitespace(options.getTitle(doc)),
description: collapseWhitespace(options.getDescription(doc)),
headings: options.getHeadings(doc).map(collapseWhitespace),
content: collapseWhitespace(options.getContent(doc)),
url: this.page.url === '/' ? '/' : this.page.url.replace(/\/$/, '')
});
return content;
});
eleventyConfig.on('eleventy.after', ({ dir }) => {
const outputFilename = join(dir.output, 'search.json');
const map = [];
const searchIndex = lunr(async function () {
let index = 0;
this.ref('id');
this.field('t', { boost: 20 });
this.field('h', { boost: 10 });
this.field('c');
for (const page of pagesToIndex) {
this.add({ id: index, t: page.title, h: page.headings, c: page.content });
map[index] = { title: page.title, description: page.description, url: page.url };
index++;
}
await mkdir(dirname(outputFilename), { recursive: true });
await writeFile(outputFilename, JSON.stringify({ searchIndex, map }), 'utf-8');
});
});
};
}

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1"/>
</svg>

Before

Width:  |  Height:  |  Size: 308 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466"/>
</svg>

Before

Width:  |  Height:  |  Size: 356 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-at" viewBox="0 0 16 16">
<path d="M13.106 7.222c0-2.967-2.249-5.032-5.482-5.032-3.35 0-5.646 2.318-5.646 5.702 0 3.493 2.235 5.708 5.762 5.708.862 0 1.689-.123 2.304-.335v-.862c-.43.199-1.354.328-2.29.328-2.926 0-4.813-1.88-4.813-4.798 0-2.844 1.921-4.881 4.594-4.881 2.735 0 4.608 1.688 4.608 4.156 0 1.682-.554 2.769-1.416 2.769-.492 0-.772-.28-.772-.76V5.206H8.923v.834h-.11c-.266-.595-.881-.964-1.6-.964-1.4 0-2.378 1.162-2.378 2.823 0 1.737.957 2.906 2.379 2.906.8 0 1.415-.39 1.709-1.087h.11c.081.67.703 1.148 1.503 1.148 1.572 0 2.57-1.415 2.57-3.643zm-7.177.704c0-1.197.54-1.907 1.456-1.907.93 0 1.524.738 1.524 1.907S8.308 9.84 7.371 9.84c-.895 0-1.442-.725-1.442-1.914"/>
</svg>

Before

Width:  |  Height:  |  Size: 786 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-backpack" viewBox="0 0 16 16">
<path d="M4.04 7.43a4 4 0 0 1 7.92 0 .5.5 0 1 1-.99.14 3 3 0 0 0-5.94 0 .5.5 0 1 1-.99-.14M4 9.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5zm1 .5v3h6v-3h-1v.5a.5.5 0 0 1-1 0V10z"/>
<path d="M6 2.341V2a2 2 0 1 1 4 0v.341c2.33.824 4 3.047 4 5.659v5.5a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 2 13.5V8a6 6 0 0 1 4-5.659M7 2v.083a6 6 0 0 1 2 0V2a1 1 0 0 0-2 0m1 1a5 5 0 0 0-5 5v5.5A1.5 1.5 0 0 0 4.5 15h7a1.5 1.5 0 0 0 1.5-1.5V8a5 5 0 0 0-5-5"/>
</svg>

Before

Width:  |  Height:  |  Size: 607 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bag" viewBox="0 0 16 16">
<path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1m3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 305 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-blockquote-left" viewBox="0 0 16 16">
<path d="M2.5 3a.5.5 0 0 0 0 1h11a.5.5 0 0 0 0-1zm5 3a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1zm0 3a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1zm-5 3a.5.5 0 0 0 0 1h11a.5.5 0 0 0 0-1zm.79-5.373q.168-.117.444-.275L3.524 6q-.183.111-.452.287-.27.176-.51.428a2.4 2.4 0 0 0-.398.562Q2 7.587 2 7.969q0 .54.217.873.217.328.72.328.322 0 .504-.211a.7.7 0 0 0 .188-.463q0-.345-.211-.521-.205-.182-.568-.182h-.282q.036-.305.123-.498a1.4 1.4 0 0 1 .252-.37 2 2 0 0 1 .346-.298zm2.167 0q.17-.117.445-.275L5.692 6q-.183.111-.452.287-.27.176-.51.428a2.4 2.4 0 0 0-.398.562q-.165.31-.164.692 0 .54.217.873.217.328.72.328.322 0 .504-.211a.7.7 0 0 0 .188-.463q0-.345-.211-.521-.205-.182-.568-.182h-.282a1.8 1.8 0 0 1 .118-.492q.087-.194.257-.375a2 2 0 0 1 .346-.3z"/>
</svg>

Before

Width:  |  Height:  |  Size: 872 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-bold" viewBox="0 0 16 16">
<path d="M8.21 13c2.106 0 3.412-1.087 3.412-2.823 0-1.306-.984-2.283-2.324-2.386v-.055a2.176 2.176 0 0 0 1.852-2.14c0-1.51-1.162-2.46-3.014-2.46H3.843V13zM5.908 4.674h1.696c.963 0 1.517.451 1.517 1.244 0 .834-.629 1.32-1.73 1.32H5.908V4.673zm0 6.788V8.598h1.73c1.217 0 1.88.492 1.88 1.415 0 .943-.643 1.449-1.832 1.449H5.907z"/>
</svg>

Before

Width:  |  Height:  |  Size: 465 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-book" viewBox="0 0 16 16">
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783"/>
</svg>

Before

Width:  |  Height:  |  Size: 770 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bookmark" viewBox="0 0 16 16">
<path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v13.5a.5.5 0 0 1-.777.416L8 13.101l-5.223 2.815A.5.5 0 0 1 2 15.5zm2-1a1 1 0 0 0-1 1v12.566l4.723-2.482a.5.5 0 0 1 .554 0L13 14.566V2a1 1 0 0 0-1-1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 330 B

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-boombox" viewBox="0 0 16 16">
<path d="M2.5 5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m2 0a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m7.5-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0m1.5.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m-7-1a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zm5.5 6.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0"/>
<path d="M11.5 13a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5m0-1a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3M5 10.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0"/>
<path d="M7 10.5a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0m-1 0a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0"/>
<path d="M14 0a.5.5 0 0 1 .5.5V2h.5a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h12.5V.5A.5.5 0 0 1 14 0M1 3v3h14V3zm14 4H1v7h14z"/>
</svg>

Before

Width:  |  Height:  |  Size: 754 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bug" viewBox="0 0 16 16">
<path d="M4.355.522a.5.5 0 0 1 .623.333l.291.956A5 5 0 0 1 8 1c1.007 0 1.946.298 2.731.811l.29-.956a.5.5 0 1 1 .957.29l-.41 1.352A5 5 0 0 1 13 6h.5a.5.5 0 0 0 .5-.5V5a.5.5 0 0 1 1 0v.5A1.5 1.5 0 0 1 13.5 7H13v1h1.5a.5.5 0 0 1 0 1H13v1h.5a1.5 1.5 0 0 1 1.5 1.5v.5a.5.5 0 1 1-1 0v-.5a.5.5 0 0 0-.5-.5H13a5 5 0 0 1-10 0h-.5a.5.5 0 0 0-.5.5v.5a.5.5 0 1 1-1 0v-.5A1.5 1.5 0 0 1 2.5 10H3V9H1.5a.5.5 0 0 1 0-1H3V7h-.5A1.5 1.5 0 0 1 1 5.5V5a.5.5 0 0 1 1 0v.5a.5.5 0 0 0 .5.5H3c0-1.364.547-2.601 1.432-3.503l-.41-1.352a.5.5 0 0 1 .333-.623M4 7v4a4 4 0 0 0 3.5 3.97V7zm4.5 0v7.97A4 4 0 0 0 12 11V7zM12 6a4 4 0 0 0-1.334-2.982A3.98 3.98 0 0 0 8 2a3.98 3.98 0 0 0-2.667 1.018A4 4 0 0 0 4 6z"/>
</svg>

Before

Width:  |  Height:  |  Size: 812 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 322 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-car-front" viewBox="0 0 16 16">
<path d="M4 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0m10 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M6 8a1 1 0 0 0 0 2h4a1 1 0 1 0 0-2zM4.862 4.276 3.906 6.19a.51.51 0 0 0 .497.731c.91-.073 2.35-.17 3.597-.17s2.688.097 3.597.17a.51.51 0 0 0 .497-.731l-.956-1.913A.5.5 0 0 0 10.691 4H5.309a.5.5 0 0 0-.447.276"/>
<path d="M2.52 3.515A2.5 2.5 0 0 1 4.82 2h6.362c1 0 1.904.596 2.298 1.515l.792 1.848c.075.175.21.319.38.404.5.25.855.715.965 1.262l.335 1.679q.05.242.049.49v.413c0 .814-.39 1.543-1 1.997V13.5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-1.338c-1.292.048-2.745.088-4 .088s-2.708-.04-4-.088V13.5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-1.892c-.61-.454-1-1.183-1-1.997v-.413a2.5 2.5 0 0 1 .049-.49l.335-1.68c.11-.546.465-1.012.964-1.261a.8.8 0 0 0 .381-.404l.792-1.848ZM4.82 3a1.5 1.5 0 0 0-1.379.91l-.792 1.847a1.8 1.8 0 0 1-.853.904.8.8 0 0 0-.43.564L1.03 8.904a1.5 1.5 0 0 0-.03.294v.413c0 .796.62 1.448 1.408 1.484 1.555.07 3.786.155 5.592.155s4.037-.084 5.592-.155A1.48 1.48 0 0 0 15 9.611v-.413q0-.148-.03-.294l-.335-1.68a.8.8 0 0 0-.43-.563 1.8 1.8 0 0 1-.853-.904l-.792-1.848A1.5 1.5 0 0 0 11.18 3z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cart" viewBox="0 0 16 16">
<path d="M0 1.5A.5.5 0 0 1 .5 1H2a.5.5 0 0 1 .485.379L2.89 3H14.5a.5.5 0 0 1 .491.592l-1.5 8A.5.5 0 0 1 13 12H4a.5.5 0 0 1-.491-.408L2.01 3.607 1.61 2H.5a.5.5 0 0 1-.5-.5M3.102 4l1.313 7h8.17l1.313-7zM5 12a2 2 0 1 0 0 4 2 2 0 0 0 0-4m7 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4m-7 1a1 1 0 1 1 0 2 1 1 0 0 1 0-2m7 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2"/>
</svg>

Before

Width:  |  Height:  |  Size: 465 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-lg" viewBox="0 0 16 16">
<path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z"/>
</svg>

Before

Width:  |  Height:  |  Size: 321 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708"/>
</svg>

Before

Width:  |  Height:  |  Size: 289 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-up" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z"/>
</svg>

Before

Width:  |  Height:  |  Size: 267 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
</svg>

Before

Width:  |  Height:  |  Size: 460 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4"/>
</svg>

Before

Width:  |  Height:  |  Size: 333 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clock" viewBox="0 0 16 16">
<path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0"/>
</svg>

Before

Width:  |  Height:  |  Size: 305 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-code" viewBox="0 0 16 16">
<path d="M5.854 4.854a.5.5 0 1 0-.708-.708l-3.5 3.5a.5.5 0 0 0 0 .708l3.5 3.5a.5.5 0 0 0 .708-.708L2.707 8zm4.292 0a.5.5 0 0 1 .708-.708l3.5 3.5a.5.5 0 0 1 0 .708l-3.5 3.5a.5.5 0 0 1-.708-.708L13.293 8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 337 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-credit-card" viewBox="0 0 16 16">
<path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v1h14V4a1 1 0 0 0-1-1zm13 4H1v5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
<path d="M2 10a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 383 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3m5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3m5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3"/>
</svg>

Before

Width:  |  Height:  |  Size: 272 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-envelope" viewBox="0 0 16 16">
<path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/>
</svg>

Before

Width:  |  Height:  |  Size: 421 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-emoji-smile" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="M4.285 9.567a.5.5 0 0 1 .683.183A3.5 3.5 0 0 0 8 11.5a3.5 3.5 0 0 0 3.032-1.75.5.5 0 1 1 .866.5A4.5 4.5 0 0 1 8 12.5a4.5 4.5 0 0 1-3.898-2.25.5.5 0 0 1 .183-.683M7 6.5C7 7.328 6.552 8 6 8s-1-.672-1-1.5S5.448 5 6 5s1 .672 1 1.5m4 0c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5"/>
</svg>

Before

Width:  |  Height:  |  Size: 525 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-flag" viewBox="0 0 16 16">
<path d="M14.778.085A.5.5 0 0 1 15 .5V8a.5.5 0 0 1-.314.464L14.5 8l.186.464-.003.001-.006.003-.023.009a12 12 0 0 1-.397.15c-.264.095-.631.223-1.047.35-.816.252-1.879.523-2.71.523-.847 0-1.548-.28-2.158-.525l-.028-.01C7.68 8.71 7.14 8.5 6.5 8.5c-.7 0-1.638.23-2.437.477A20 20 0 0 0 3 9.342V15.5a.5.5 0 0 1-1 0V.5a.5.5 0 0 1 1 0v.282c.226-.079.496-.17.79-.26C4.606.272 5.67 0 6.5 0c.84 0 1.524.277 2.121.519l.043.018C9.286.788 9.828 1 10.5 1c.7 0 1.638-.23 2.437-.477a20 20 0 0 0 1.349-.476l.019-.007.004-.002h.001M14 1.221c-.22.078-.48.167-.766.255-.81.252-1.872.523-2.734.523-.886 0-1.592-.286-2.203-.534l-.008-.003C7.662 1.21 7.139 1 6.5 1c-.669 0-1.606.229-2.415.478A21 21 0 0 0 3 1.845v6.433c.22-.078.48-.167.766-.255C4.576 7.77 5.638 7.5 6.5 7.5c.847 0 1.548.28 2.158.525l.028.01C9.32 8.29 9.86 8.5 10.5 8.5c.668 0 1.606-.229 2.415-.478A21 21 0 0 0 14 7.655V1.222z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1003 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type" viewBox="0 0 16 16">
<path d="m2.244 13.081.943-2.803H6.66l.944 2.803H8.86L5.54 3.75H4.322L1 13.081zm2.7-7.923L6.34 9.314H3.51l1.4-4.156zm9.146 7.027h.035v.896h1.128V8.125c0-1.51-1.114-2.345-2.646-2.345-1.736 0-2.59.916-2.666 2.174h1.108c.068-.718.595-1.19 1.517-1.19.971 0 1.518.52 1.518 1.464v.731H12.19c-1.647.007-2.522.8-2.522 2.058 0 1.319.957 2.18 2.345 2.18 1.06 0 1.716-.43 2.078-1.011zm-1.763.035c-.752 0-1.456-.397-1.456-1.244 0-.65.424-1.115 1.408-1.115h1.805v.834c0 .896-.752 1.525-1.757 1.525"/>
</svg>

Before

Width:  |  Height:  |  Size: 619 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-controller" viewBox="0 0 16 16">
<path d="M11.5 6.027a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0m-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m2.5-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0m-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1m-6.5-3h1v1h1v1h-1v1h-1v-1h-1v-1h1z"/>
<path d="M3.051 3.26a.5.5 0 0 1 .354-.613l1.932-.518a.5.5 0 0 1 .62.39c.655-.079 1.35-.117 2.043-.117.72 0 1.443.041 2.12.126a.5.5 0 0 1 .622-.399l1.932.518a.5.5 0 0 1 .306.729q.211.136.373.297c.408.408.78 1.05 1.095 1.772.32.733.599 1.591.805 2.466s.34 1.78.364 2.606c.024.816-.059 1.602-.328 2.21a1.42 1.42 0 0 1-1.445.83c-.636-.067-1.115-.394-1.513-.773-.245-.232-.496-.526-.739-.808-.126-.148-.25-.292-.368-.423-.728-.804-1.597-1.527-3.224-1.527s-2.496.723-3.224 1.527c-.119.131-.242.275-.368.423-.243.282-.494.575-.739.808-.398.38-.877.706-1.513.773a1.42 1.42 0 0 1-1.445-.83c-.27-.608-.352-1.395-.329-2.21.024-.826.16-1.73.365-2.606.206-.875.486-1.733.805-2.466.315-.722.687-1.364 1.094-1.772a2.3 2.3 0 0 1 .433-.335l-.028-.079zm2.036.412c-.877.185-1.469.443-1.733.708-.276.276-.587.783-.885 1.465a14 14 0 0 0-.748 2.295 12.4 12.4 0 0 0-.339 2.406c-.022.755.062 1.368.243 1.776a.42.42 0 0 0 .426.24c.327-.034.61-.199.929-.502.212-.202.4-.423.615-.674.133-.156.276-.323.44-.504C4.861 9.969 5.978 9.027 8 9.027s3.139.942 3.965 1.855c.164.181.307.348.44.504.214.251.403.472.615.674.318.303.601.468.929.503a.42.42 0 0 0 .426-.241c.18-.408.265-1.02.243-1.776a12.4 12.4 0 0 0-.339-2.406 14 14 0 0 0-.748-2.295c-.298-.682-.61-1.19-.885-1.465-.264-.265-.856-.523-1.733-.708-.85-.179-1.877-.27-2.913-.27s-2.063.091-2.913.27"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-globe" viewBox="0 0 16 16">
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m7.5-6.923c-.67.204-1.335.82-1.887 1.855A8 8 0 0 0 5.145 4H7.5zM4.09 4a9.3 9.3 0 0 1 .64-1.539 7 7 0 0 1 .597-.933A7.03 7.03 0 0 0 2.255 4zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a7 7 0 0 0-.656 2.5zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5zM8.5 5v2.5h2.99a12.5 12.5 0 0 0-.337-2.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5zM5.145 12q.208.58.468 1.068c.552 1.035 1.218 1.65 1.887 1.855V12zm.182 2.472a7 7 0 0 1-.597-.933A9.3 9.3 0 0 1 4.09 12H2.255a7 7 0 0 0 3.072 2.472M3.82 11a13.7 13.7 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5zm6.853 3.472A7 7 0 0 0 13.745 12H11.91a9.3 9.3 0 0 1-.64 1.539 7 7 0 0 1-.597.933M8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855q.26-.487.468-1.068zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.7 13.7 0 0 1-.312 2.5m2.802-3.5a7 7 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7 7 0 0 0-3.072-2.472c.218.284.418.598.597.933M10.855 4a8 8 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-italic" viewBox="0 0 16 16">
<path d="M7.991 11.674 9.53 4.455c.123-.595.246-.71 1.347-.807l.11-.52H7.211l-.11.52c1.06.096 1.128.212 1.005.807L6.57 11.674c-.123.595-.246.71-1.346.806l-.11.52h3.774l.11-.52c-1.06-.095-1.129-.211-1.006-.806z"/>
</svg>

Before

Width:  |  Height:  |  Size: 351 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-keyboard" viewBox="0 0 16 16">
<path d="M14 5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zM2 4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z"/>
<path d="M13 10.25a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25zm0-2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25zm-5 0A.25.25 0 0 1 8.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 8 8.75zm2 0a.25.25 0 0 1 .25-.25h1.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-1.5a.25.25 0 0 1-.25-.25zm1 2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25zm-5-2A.25.25 0 0 1 6.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 6 8.75zm-2 0A.25.25 0 0 1 4.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 4 8.75zm-2 0A.25.25 0 0 1 2.25 8h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 2 8.75zm11-2a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25zm-2 0a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25zm-2 0A.25.25 0 0 1 9.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 9 6.75zm-2 0A.25.25 0 0 1 7.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 7 6.75zm-2 0A.25.25 0 0 1 5.25 6h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5A.25.25 0 0 1 5 6.75zm-3 0A.25.25 0 0 1 2.25 6h1.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-1.5A.25.25 0 0 1 2 6.75zm0 4a.25.25 0 0 1 .25-.25h.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-.5a.25.25 0 0 1-.25-.25zm2 0a.25.25 0 0 1 .25-.25h5.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-5.5a.25.25 0 0 1-.25-.25z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bank" viewBox="0 0 16 16">
<path d="m8 0 6.61 3h.89a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5H15v7a.5.5 0 0 1 .485.38l.5 2a.498.498 0 0 1-.485.62H.5a.498.498 0 0 1-.485-.62l.5-2A.5.5 0 0 1 1 13V6H.5a.5.5 0 0 1-.5-.5v-2A.5.5 0 0 1 .5 3h.89zM3.777 3h8.447L8 1zM2 6v7h1V6zm2 0v7h2.5V6zm3.5 0v7h1V6zm2 0v7H12V6zM13 6v7h1V6zm2-1V4H1v1zm-.39 9H1.39l-.25 1h13.72z"/>
</svg>

Before

Width:  |  Height:  |  Size: 456 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link" viewBox="0 0 16 16">
<path d="M6.354 5.5H4a3 3 0 0 0 0 6h3a3 3 0 0 0 2.83-4H9q-.13 0-.25.031A2 2 0 0 1 7 10.5H4a2 2 0 1 1 0-4h1.535c.218-.376.495-.714.82-1z"/>
<path d="M9 5.5a3 3 0 0 0-2.83 4h1.098A2 2 0 0 1 9 6.5h3a2 2 0 1 1 0 4h-1.535a4 4 0 0 1-.82 1H12a3 3 0 1 0 0-6z"/>
</svg>

Before

Width:  |  Height:  |  Size: 387 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list-ol" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5"/>
<path d="M1.713 11.865v-.474H2c.217 0 .363-.137.363-.317 0-.185-.158-.31-.361-.31-.223 0-.367.152-.373.31h-.59c.016-.467.373-.787.986-.787.588-.002.954.291.957.703a.595.595 0 0 1-.492.594v.033a.615.615 0 0 1 .569.631c.003.533-.502.8-1.051.8-.656 0-1-.37-1.008-.794h.582c.008.178.186.306.422.309.254 0 .424-.145.422-.35-.002-.195-.155-.348-.414-.348h-.3zm-.004-4.699h-.604v-.035c0-.408.295-.844.958-.844.583 0 .96.326.96.756 0 .389-.257.617-.476.848l-.537.572v.03h1.054V9H1.143v-.395l.957-.99c.138-.142.293-.304.293-.508 0-.18-.147-.32-.342-.32a.33.33 0 0 0-.342.338zM2.564 5h-.635V2.924h-.031l-.598.42v-.567l.629-.443h.635z"/>
</svg>

Before

Width:  |  Height:  |  Size: 973 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list-ul" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m-3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2m0 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2m0 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2"/>
</svg>

Before

Width:  |  Height:  |  Size: 441 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-geo-alt" viewBox="0 0 16 16">
<path d="M12.166 8.94c-.524 1.062-1.234 2.12-1.96 3.07A32 32 0 0 1 8 14.58a32 32 0 0 1-2.206-2.57c-.726-.95-1.436-2.008-1.96-3.07C3.304 7.867 3 6.862 3 6a5 5 0 0 1 10 0c0 .862-.305 1.867-.834 2.94M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10"/>
<path d="M8 8a2 2 0 1 1 0-4 2 2 0 0 1 0 4m0 1a3 3 0 1 0 0-6 3 3 0 0 0 0 6"/>
</svg>

Before

Width:  |  Height:  |  Size: 463 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-lock" viewBox="0 0 16 16">
<path d="M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2m3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2M5 8h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1"/>
</svg>

Before

Width:  |  Height:  |  Size: 334 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>
</svg>

Before

Width:  |  Height:  |  Size: 315 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-mic" viewBox="0 0 16 16">
<path d="M3.5 6.5A.5.5 0 0 1 4 7v1a4 4 0 0 0 8 0V7a.5.5 0 0 1 1 0v1a5 5 0 0 1-4.5 4.975V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 .5-.5"/>
<path d="M10 8a2 2 0 1 1-4 0V3a2 2 0 1 1 4 0zM8 0a3 3 0 0 0-3 3v5a3 3 0 0 0 6 0V3a3 3 0 0 0-3-3"/>
</svg>

Before

Width:  |  Height:  |  Size: 402 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-lg" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8"/>
</svg>

Before

Width:  |  Height:  |  Size: 225 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cup-hot" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M.5 6a.5.5 0 0 0-.488.608l1.652 7.434A2.5 2.5 0 0 0 4.104 16h5.792a2.5 2.5 0 0 0 2.44-1.958l.131-.59a3 3 0 0 0 1.3-5.854l.221-.99A.5.5 0 0 0 13.5 6zM13 12.5a2 2 0 0 1-.316-.025l.867-3.898A2.001 2.001 0 0 1 13 12.5M2.64 13.825 1.123 7h11.754l-1.517 6.825A1.5 1.5 0 0 1 9.896 15H4.104a1.5 1.5 0 0 1-1.464-1.175"/>
<path d="m4.4.8-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 3.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 3.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 3 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 4.4.8m3 0-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.253.382l-.018.025-.005.008-.002.002A.5.5 0 0 1 6.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 6.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 6 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 7.4.8m3 0-.003.004-.014.019a4 4 0 0 0-.204.31 2 2 0 0 0-.141.267c-.026.06-.034.092-.037.103v.004a.6.6 0 0 0 .091.248c.075.133.178.272.308.445l.01.012c.118.158.26.347.37.543.112.2.22.455.22.745 0 .188-.065.368-.119.494a3 3 0 0 1-.202.388 5 5 0 0 1-.252.382l-.019.025-.005.008-.002.002A.5.5 0 0 1 9.6 4.2l.003-.004.014-.019a4 4 0 0 0 .204-.31 2 2 0 0 0 .141-.267c.026-.06.034-.092.037-.103a.6.6 0 0 0-.09-.252A4 4 0 0 0 9.6 2.8l-.01-.012a5 5 0 0 1-.37-.543A1.53 1.53 0 0 1 9 1.5c0-.188.065-.368.119-.494.059-.138.134-.274.202-.388a6 6 0 0 1 .253-.382l.025-.035A.5.5 0 0 1 10.4.8"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-music-note-beamed" viewBox="0 0 16 16">
<path d="M6 13c0 1.105-1.12 2-2.5 2S1 14.105 1 13s1.12-2 2.5-2 2.5.896 2.5 2m9-2c0 1.105-1.12 2-2.5 2s-2.5-.895-2.5-2 1.12-2 2.5-2 2.5.895 2.5 2"/>
<path fill-rule="evenodd" d="M14 11V2h1v9zM6 3v10H5V3z"/>
<path d="M5 2.905a1 1 0 0 1 .9-.995l8-.8a1 1 0 0 1 1.1.995V3L5 4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 423 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-palette" viewBox="0 0 16 16">
<path d="M8 5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3m4 3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M5.5 7a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m.5 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3"/>
<path d="M16 8c0 3.15-1.866 2.585-3.567 2.07C11.42 9.763 10.465 9.473 10 10c-.603.683-.475 1.819-.351 2.92C9.826 14.495 9.996 16 8 16a8 8 0 1 1 8-8m-8 7c.611 0 .654-.171.655-.176.078-.146.124-.464.07-1.119-.014-.168-.037-.37-.061-.591-.052-.464-.112-1.005-.118-1.462-.01-.707.083-1.61.704-2.314.369-.417.845-.578 1.272-.618.404-.038.812.026 1.16.104.343.077.702.186 1.025.284l.028.008c.346.105.658.199.953.266.653.148.904.083.991.024C14.717 9.38 15 9.161 15 8a7 7 0 1 0-7 7"/>
</svg>

Before

Width:  |  Height:  |  Size: 789 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-send" viewBox="0 0 16 16">
<path d="M15.854.146a.5.5 0 0 1 .11.54l-5.819 14.547a.75.75 0 0 1-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 0 1 .124-1.33L15.314.037a.5.5 0 0 1 .54.11ZM6.636 10.07l2.761 4.338L14.13 2.576zm6.787-8.201L1.591 6.602l4.339 2.76z"/>
</svg>

Before

Width:  |  Height:  |  Size: 360 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-lg" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2"/>
</svg>

Before

Width:  |  Height:  |  Size: 267 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stars" viewBox="0 0 16 16">
<path d="M7.657 6.247c.11-.33.576-.33.686 0l.645 1.937a2.89 2.89 0 0 0 1.829 1.828l1.936.645c.33.11.33.576 0 .686l-1.937.645a2.89 2.89 0 0 0-1.828 1.829l-.645 1.936a.361.361 0 0 1-.686 0l-.645-1.937a2.89 2.89 0 0 0-1.828-1.828l-1.937-.645a.361.361 0 0 1 0-.686l1.937-.645a2.89 2.89 0 0 0 1.828-1.828zM3.794 1.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387A1.73 1.73 0 0 0 4.593 5.69l-.387 1.162a.217.217 0 0 1-.412 0L3.407 5.69A1.73 1.73 0 0 0 2.31 4.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387A1.73 1.73 0 0 0 3.407 2.31zM10.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.16 1.16 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.16 1.16 0 0 0-.732-.732L9.1 2.137a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732z"/>
</svg>

Before

Width:  |  Height:  |  Size: 998 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-star-fill" viewBox="0 0 16 16">
<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
</svg>

Before

Width:  |  Height:  |  Size: 399 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-type-strikethrough" viewBox="0 0 16 16">
<path d="M6.333 5.686c0 .31.083.581.27.814H5.166a2.8 2.8 0 0 1-.099-.76c0-1.627 1.436-2.768 3.48-2.768 1.969 0 3.39 1.175 3.445 2.85h-1.23c-.11-1.08-.964-1.743-2.25-1.743-1.23 0-2.18.602-2.18 1.607zm2.194 7.478c-2.153 0-3.589-1.107-3.705-2.81h1.23c.144 1.06 1.129 1.703 2.544 1.703 1.34 0 2.31-.705 2.31-1.675 0-.827-.547-1.374-1.914-1.675L8.046 8.5H1v-1h14v1h-3.504c.468.437.675.994.675 1.697 0 1.826-1.436 2.967-3.644 2.967"/>
</svg>

Before

Width:  |  Height:  |  Size: 574 B

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-terminal" viewBox="0 0 16 16">
<path d="M6 9a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3A.5.5 0 0 1 6 9M3.854 4.146a.5.5 0 1 0-.708.708L4.793 6.5 3.146 8.146a.5.5 0 1 0 .708.708l2-2a.5.5 0 0 0 0-.708z"/>
<path d="M2 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm12 1a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1z"/>
</svg>

Before

Width:  |  Height:  |  Size: 454 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trophy" viewBox="0 0 16 16">
<path d="M2.5.5A.5.5 0 0 1 3 0h10a.5.5 0 0 1 .5.5q0 .807-.034 1.536a3 3 0 1 1-1.133 5.89c-.79 1.865-1.878 2.777-2.833 3.011v2.173l1.425.356c.194.048.377.135.537.255L13.3 15.1a.5.5 0 0 1-.3.9H3a.5.5 0 0 1-.3-.9l1.838-1.379c.16-.12.343-.207.537-.255L6.5 13.11v-2.173c-.955-.234-2.043-1.146-2.833-3.012a3 3 0 1 1-1.132-5.89A33 33 0 0 1 2.5.5m.099 2.54a2 2 0 0 0 .72 3.935c-.333-1.05-.588-2.346-.72-3.935m10.083 3.935a2 2 0 0 0 .72-3.935c-.133 1.59-.388 2.885-.72 3.935M3.504 1q.01.775.056 1.469c.13 2.028.457 3.546.87 4.667C5.294 9.48 6.484 10 7 10a.5.5 0 0 1 .5.5v2.61a1 1 0 0 1-.757.97l-1.426.356a.5.5 0 0 0-.179.085L4.5 15h7l-.638-.479a.5.5 0 0 0-.18-.085l-1.425-.356a1 1 0 0 1-.757-.97V10.5A.5.5 0 0 1 9 10c.516 0 1.706-.52 2.57-2.864.413-1.12.74-2.64.87-4.667q.045-.694.056-1.469z"/>
</svg>

Before

Width:  |  Height:  |  Size: 919 B

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person" viewBox="0 0 16 16">
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10s-3.516.68-4.168 1.332c-.678.678-.83 1.418-.832 1.664z"/>
</svg>

Before

Width:  |  Height:  |  Size: 375 B

Some files were not shown because too many files have changed in this diff Show More