Improved discoverability of icons in the documentation

This commit is contained in:
squidfunk 2022-01-16 17:27:14 +01:00
parent a919199008
commit 840a00a6f6
17 changed files with 184 additions and 83 deletions

View File

@ -49,8 +49,16 @@ theme:
<type>: <icon> # (1)!
```
1. Set `<type`> to any of the [supported types] and `<icon>` to any valid icon
shortcode, which you can find by using the [icon search].
1. Enter a few keywords to find the perfect icon using our [icon search] and
click on the shortcode to copy it to your clipboard:
<div class="mdx-iconsearch" data-mdx-component="iconsearch">
<input class="md-input md-input--stretch mdx-iconsearch__input" placeholder="Search icon" data-mdx-component="iconsearch-query" value="alert" />
<div class="mdx-iconsearch-result" data-mdx-component="iconsearch-result" data-mdx-mode="file">
<div class="mdx-iconsearch-result__meta"></div>
<ol class="mdx-iconsearch-result__list"></ol>
</div>
</div>
??? example "Expand to show alternate icon sets"

View File

@ -69,7 +69,7 @@ CSS class selectors.
### Adding icon buttons
Of course, icons can be added to all types of buttons by using the [icon syntax]
together with any valid icon shortcode, which can be easily found with a few keystrokes through the [icon search].
together with any valid icon shortcode, which can be easily found with a few keystrokes through our [icon search].
``` markdown title="Button with icon"
[Send :fontawesome-solid-paper-plane:](#){ .md-button }

View File

@ -198,10 +198,21 @@ reference any icon that's [bundled with the theme][icon search] with Jinja's
``` html
<span class="twemoji">
{% include ".icons/fontawesome/brands/twitter.svg" %}
{% include ".icons/fontawesome/brands/twitter.svg" %} <!-- (1)! -->
</span>
```
1. Enter a few keywords to find the perfect icon using our [icon search] and
click on the shortcode to copy it to your clipboard:
<div class="mdx-iconsearch" data-mdx-component="iconsearch">
<input class="md-input md-input--stretch mdx-iconsearch__input" placeholder="Search icon" data-mdx-component="iconsearch-query" value="brands twitter" />
<div class="mdx-iconsearch-result" data-mdx-component="iconsearch-result" data-mdx-mode="file">
<div class="mdx-iconsearch-result__meta"></div>
<ol class="mdx-iconsearch-result__list"></ol>
</div>
</div>
This is exactly what Material for MkDocs does in its templates.
[extending the theme]: ../customization.md#extending-the-theme

View File

@ -88,8 +88,16 @@ icon: material/emoticon-happy # (1)!
...
```
1. Check out the left sidebar to see icons in action! Also check out our
[icon search] to find the perfect icon with a few keystrokes.
1. Enter a few keywords to find the perfect icon using our [icon search] and
click on the shortcode to copy it to your clipboard:
<div class="mdx-iconsearch" data-mdx-component="iconsearch">
<input class="md-input md-input--stretch mdx-iconsearch__input" placeholder="Search icon" data-mdx-component="iconsearch-query" value="emoticon happy" />
<div class="mdx-iconsearch-result" data-mdx-component="iconsearch-result" data-mdx-mode="file">
<div class="mdx-iconsearch-result__meta"></div>
<ol class="mdx-iconsearch-result__list"></ol>
</div>
</div>
[Insiders]: ../insiders/index.md
[icon search]: icons-emojis.md#search

View File

@ -56,15 +56,26 @@ repo_name: squidfunk/mkdocs-material
[`fontawesome/brands/git-alt`][icon.repo default]
While the default repository icon is a generic git icon, it can be set to
[any icon bundled with the theme][custom icons] by referencing a valid icon
path in `mkdocs.yml`:
any icon bundled with the theme by referencing a valid icon path in
`mkdocs.yml`:
``` yaml
theme:
icon:
repo: fontawesome/brands/git-alt
repo: fontawesome/brands/git-alt # (1)
```
1. Enter a few keywords to find the perfect icon using our [icon search] and
click on the shortcode to copy it to your clipboard:
<div class="mdx-iconsearch" data-mdx-component="iconsearch">
<input class="md-input md-input--stretch mdx-iconsearch__input" placeholder="Search icon" data-mdx-component="iconsearch-query" value="git" />
<div class="mdx-iconsearch-result" data-mdx-component="iconsearch-result" data-mdx-mode="file">
<div class="mdx-iconsearch-result__meta"></div>
<ol class="mdx-iconsearch-result__list"></ol>
</div>
</div>
Some popular choices:
- :fontawesome-brands-git: `fontawesome/brands/git`
@ -80,7 +91,7 @@ Some popular choices:
[icon.repo support]: https://github.com/squidfunk/mkdocs-material/releases/tag/5.0.0
[icon.repo default]: https://github.com/squidfunk/mkdocs-material/blob/master/material/.icons/fontawesome/brands/git-alt.svg
[custom icons]: https://github.com/squidfunk/mkdocs-material/tree/master/material/.icons
[icon search]: ../reference/icons-emojis.md#search
### Edit button

View File

@ -34,11 +34,23 @@ Add the following lines to `mkdocs.yml`:
``` yaml
theme:
icon:
logo: material/library
logo: material/library # (1)!
```
1. Enter a few keywords to find the perfect icon using our [icon search] and
click on the shortcode to copy it to your clipboard:
<div class="mdx-iconsearch" data-mdx-component="iconsearch">
<input class="md-input md-input--stretch mdx-iconsearch__input" placeholder="Search icon" data-mdx-component="iconsearch-query" value="material library" />
<div class="mdx-iconsearch-result" data-mdx-component="iconsearch-result" data-mdx-mode="file">
<div class="mdx-iconsearch-result__meta"></div>
<ol class="mdx-iconsearch-result__list"></ol>
</div>
</div>
[logo support]: https://github.com/squidfunk/mkdocs-material/releases/tag/0.1.0
[logo default]: https://github.com/squidfunk/mkdocs-material/blob/master/material/.icons/material/library.svg
[icon search]: ../reference/icons-emojis.md#search
Normally, the logo in the header and sidebar links to the homepage of the
documentation, which is the same as `site_url`. This behavior can be changed

View File

@ -25,17 +25,28 @@ with:
``` yaml
extra:
social:
- icon: fontawesome/brands/twitter
- icon: fontawesome/brands/twitter # (1)!
link: https://twitter.com/squidfunk
```
1. Enter a few keywords to find the perfect icon using our [icon search] and
click on the shortcode to copy it to your clipboard:
<div class="mdx-iconsearch" data-mdx-component="iconsearch">
<input class="md-input md-input--stretch mdx-iconsearch__input" placeholder="Search icon" data-mdx-component="iconsearch-query" value="brands twitter" />
<div class="mdx-iconsearch-result" data-mdx-component="iconsearch-result" data-mdx-mode="file">
<div class="mdx-iconsearch-result__meta"></div>
<ol class="mdx-iconsearch-result__list"></ol>
</div>
</div>
The following properties must be set for each link:
`icon`{ #social-icon }
: [:octicons-tag-24: 5.0.0][social.icon support] · :octicons-milestone-24:
Default: _none_ · :octicons-alert-24: Required This property must contain
a valid path to [any icon bundled with the theme][custom icons], or the
a valid path to any icon bundled with the theme, or the
build will not succeed. Some popular choices:
* :fontawesome-brands-behance: `fontawesome/brands/behance`
@ -91,7 +102,6 @@ The following properties must be set for each link:
[social support]: https://github.com/squidfunk/mkdocs-material/releases/tag/1.0.0
[social.icon support]: https://github.com/squidfunk/mkdocs-material/releases/tag/5.0.0
[social.name support]: https://github.com/squidfunk/mkdocs-material/releases/tag/5.1.5
[custom icons]: https://github.com/squidfunk/mkdocs-material/tree/master/material/.icons
### Copyright notice

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"sources":["src/overrides/assets/stylesheets/main/_typeset.scss","../../../../src/overrides/assets/stylesheets/main.scss","src/assets/stylesheets/utilities/_break.scss","src/overrides/assets/stylesheets/main/layout/_banner.scss","src/overrides/assets/stylesheets/main/layout/_hero.scss","src/overrides/assets/stylesheets/main/layout/_iconsearch.scss","src/overrides/assets/stylesheets/main/layout/_sponsorship.scss"],"names":[],"mappings":"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","file":"main.css"}
{"version":3,"sources":["src/overrides/assets/stylesheets/main/_typeset.scss","../../../../src/overrides/assets/stylesheets/main.scss","src/assets/stylesheets/utilities/_break.scss","src/overrides/assets/stylesheets/main/layout/_banner.scss","src/overrides/assets/stylesheets/main/layout/_hero.scss","src/overrides/assets/stylesheets/main/layout/_iconsearch.scss","src/overrides/assets/stylesheets/main/layout/_sponsorship.scss"],"names":[],"mappings":"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","file":"main.css"}

View File

@ -3,7 +3,7 @@
-#}
{% extends "base.html" %}
{% block extrahead %}
<link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.c1d34250.min.css' | url }}">
<link rel="stylesheet" href="{{ 'overrides/assets/stylesheets/main.b84289b2.min.css' | url }}">
{% endblock %}
{% block announce %}
<a href="https://twitter.com/squidfunk">
@ -16,5 +16,5 @@
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ 'overrides/assets/javascripts/bundle.de8129cf.min.js' | url }}"></script>
<script src="{{ 'overrides/assets/javascripts/bundle.7e64518f.min.js' | url }}"></script>
{% endblock %}

View File

@ -29,6 +29,7 @@ import {
fromEvent,
map,
merge,
startWith,
withLatestFrom
} from "rxjs"
@ -71,7 +72,8 @@ export function mountIconSearchQuery(
)
.pipe(
map(() => el.value),
distinctUntilChanged()
startWith(el.value),
distinctUntilChanged(),
)
/* Log search on blur */

View File

@ -38,7 +38,6 @@ import {
zipWith
} from "rxjs"
import { translation } from "~/_"
import {
getElement,
watchElementBoundary
@ -89,44 +88,76 @@ interface MountOptions {
/**
* Watch icon search result
*
* @param _el - Icon search result element
* @param el - Icon search result element
* @param options - Options
*
* @returns Icon search result observable
*/
export function watchIconSearchResult(
_el: HTMLElement, { index$, query$ }: WatchOptions
el: HTMLElement, { index$, query$ }: WatchOptions
): Observable<IconSearchResult> {
return combineLatest([
query$.pipe(distinctUntilKeyChanged("value")),
index$
.pipe(
map(({ icons, emojis }) => [
...Object.keys(icons.data),
...Object.keys(emojis.data)
])
)
])
.pipe(
map(([{ value }, data]) => search(data, value)),
switchMap(shortcodes => index$.pipe(
map(({ icons, emojis }) => ({
data: shortcodes.map<Icon>(shortcode => {
const category =
shortcode in icons.data
? icons
: emojis
return {
shortcode,
url: [
category.base,
category.data[shortcode]
].join("")
}
})
}))
))
)
switch (el.getAttribute("data-mdx-mode")) {
case "file":
return combineLatest([
query$.pipe(distinctUntilKeyChanged("value")),
index$
.pipe(
map(({ icons }) => Object.values(icons.data)
.map(icon => icon.replace(/\.svg$/, ""))
)
)
])
.pipe(
map(([{ value }, data]) => search(data, value)),
switchMap(files => index$.pipe(
map(({ icons }) => ({
data: files.map<Icon>(shortcode => {
return {
shortcode,
url: [
icons.base,
shortcode,
".svg"
].join("")
}
})
}))
))
)
default:
return combineLatest([
query$.pipe(distinctUntilKeyChanged("value")),
index$
.pipe(
map(({ icons, emojis }) => [
...Object.keys(icons.data),
...Object.keys(emojis.data)
])
)
])
.pipe(
map(([{ value }, data]) => search(data, value)),
switchMap(shortcodes => index$.pipe(
map(({ icons, emojis }) => ({
data: shortcodes.map<Icon>(shortcode => {
const category =
shortcode in icons.data
? icons
: emojis
return {
shortcode,
url: [
category.base,
category.data[shortcode]
].join("")
}
})
}))
))
)
}
}
/**
@ -158,27 +189,25 @@ export function mountIconSearchResult(
/* No results */
case 0:
meta.textContent = translation("search.result.none")
meta.textContent = "No matches"
break
/* One result */
case 1:
meta.textContent = translation("search.result.one")
meta.textContent = "1 match"
break
/* Multiple result */
default:
meta.textContent = translation(
"search.result.other",
round(data.length)
)
meta.textContent = `${round(data.length)} matches`
}
} else {
meta.textContent = translation("search.result.placeholder")
meta.textContent = "Type to start searching"
}
})
/* Update icon search result list */
const file = el.getAttribute("data-mdx-mode") === "file"
const list = getElement(":scope > :last-child", el)
push$
.pipe(
@ -195,7 +224,7 @@ export function mountIconSearchResult(
withLatestFrom(query$)
)
.subscribe(([result, { value }]) => list.appendChild(
renderIconSearchResult(result, value)
renderIconSearchResult(result, value, file)
))
/* Create and return component */

View File

@ -67,11 +67,12 @@ function highlight(icon: Icon, query: string): string {
*
* @param icon - Icon
* @param query - Search query
* @param file - Render as file
*
* @returns Element
*/
export function renderIconSearchResult(
icon: Icon, query: string
icon: Icon, query: string, file?: boolean
): HTMLElement {
return (
<li class="mdx-iconsearch-result__item">
@ -81,9 +82,13 @@ export function renderIconSearchResult(
<button
class="md-clipboard--inline"
title={translation("clipboard.copy")}
data-clipboard-text={`:${icon.shortcode}:`}
data-clipboard-text={file ? icon.shortcode : `:${icon.shortcode}:`}
>
<code>{`:${highlight(icon, query)}:`}</code>
<code>{
file
? highlight(icon, query)
: `:${highlight(icon, query)}:`
}</code>
</button>
</li>
)

View File

@ -63,6 +63,11 @@
scrollbar-width: thin;
scrollbar-color: var(--md-default-fg-color--lighter) transparent;
// Icon search result inside tooltip
.md-tooltip & {
max-height: px2rem(205px);
}
// Webkit scrollbar
&::-webkit-scrollbar {
width: px2rem(4px);