mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-07-28 16:52:37 -04:00
Added type selection to icon and emoji search
This commit is contained in:
@@ -33,6 +33,7 @@ export type ComponentType =
|
||||
| "iconsearch" /* Icon search */
|
||||
| "iconsearch-query" /* Icon search input */
|
||||
| "iconsearch-result" /* Icon search results */
|
||||
| "iconsearch-select" /* Icon search select */
|
||||
| "sponsorship" /* Sponsorship */
|
||||
| "sponsorship-count" /* Sponsorship count */
|
||||
| "sponsorship-total" /* Sponsorship total */
|
||||
@@ -62,6 +63,7 @@ interface ComponentTypeMap {
|
||||
"iconsearch": HTMLElement /* Icon search */
|
||||
"iconsearch-query": HTMLInputElement /* Icon search input */
|
||||
"iconsearch-result": HTMLElement /* Icon search results */
|
||||
"iconsearch-select": HTMLSelectElement
|
||||
"sponsorship": HTMLElement /* Sponsorship */
|
||||
"sponsorship-count": HTMLElement /* Sponsorship count */
|
||||
"sponsorship-total": HTMLElement /* Sponsorship total */
|
||||
|
||||
@@ -20,12 +20,16 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, merge } from "rxjs"
|
||||
import { BehaviorSubject, Observable, fromEvent, map, merge } from "rxjs"
|
||||
|
||||
import { configuration } from "~/_"
|
||||
import { requestJSON } from "~/browser"
|
||||
|
||||
import { Component, getComponentElement } from "../../_"
|
||||
import {
|
||||
Component,
|
||||
getComponentElement,
|
||||
getComponentElements
|
||||
} from "../../_"
|
||||
import {
|
||||
IconSearchQuery,
|
||||
mountIconSearchQuery
|
||||
@@ -64,6 +68,14 @@ export type IconSearch =
|
||||
| IconSearchQuery
|
||||
| IconSearchResult
|
||||
|
||||
/**
|
||||
* Icon search mode
|
||||
*/
|
||||
export type IconSearchMode =
|
||||
| "all"
|
||||
| "icons"
|
||||
| "emojis"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
@@ -87,8 +99,18 @@ export function mountIconSearch(
|
||||
const query = getComponentElement("iconsearch-query", el)
|
||||
const result = getComponentElement("iconsearch-result", el)
|
||||
|
||||
/* Retrieve select component */
|
||||
const mode$ = new BehaviorSubject<IconSearchMode>("all")
|
||||
const selects = getComponentElements("iconsearch-select", el)
|
||||
for (const select of selects) {
|
||||
fromEvent(select, "change").pipe(
|
||||
map(ev => (ev.target as HTMLSelectElement).value as IconSearchMode)
|
||||
)
|
||||
.subscribe(mode$)
|
||||
}
|
||||
|
||||
/* Create and return component */
|
||||
const query$ = mountIconSearchQuery(query)
|
||||
const result$ = mountIconSearchResult(result, { index$, query$ })
|
||||
const result$ = mountIconSearchResult(result, { index$, query$, mode$ })
|
||||
return merge(query$, result$)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
Subject,
|
||||
bufferCount,
|
||||
combineLatest,
|
||||
combineLatestWith,
|
||||
distinctUntilKeyChanged,
|
||||
filter,
|
||||
finalize,
|
||||
@@ -47,7 +48,7 @@ import { round } from "~/utilities"
|
||||
import { Icon, renderIconSearchResult } from "_/templates"
|
||||
|
||||
import { Component } from "../../_"
|
||||
import { IconSearchIndex } from "../_"
|
||||
import { IconSearchIndex, IconSearchMode } from "../_"
|
||||
import { IconSearchQuery } from "../query"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -71,6 +72,7 @@ export interface IconSearchResult {
|
||||
interface WatchOptions {
|
||||
index$: Observable<IconSearchIndex> /* Search index observable */
|
||||
query$: Observable<IconSearchQuery> /* Search query observable */
|
||||
mode$: Observable<IconSearchMode> /* Search mode observable */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,6 +81,7 @@ interface WatchOptions {
|
||||
interface MountOptions {
|
||||
index$: Observable<IconSearchIndex> /* Search index observable */
|
||||
query$: Observable<IconSearchQuery> /* Search query observable */
|
||||
mode$: Observable<IconSearchMode> /* Search mode observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -94,7 +97,7 @@ interface MountOptions {
|
||||
* @returns Icon search result observable
|
||||
*/
|
||||
export function watchIconSearchResult(
|
||||
el: HTMLElement, { index$, query$ }: WatchOptions
|
||||
el: HTMLElement, { index$, query$, mode$ }: WatchOptions
|
||||
): Observable<IconSearchResult> {
|
||||
switch (el.getAttribute("data-mdx-mode")) {
|
||||
|
||||
@@ -131,9 +134,14 @@ export function watchIconSearchResult(
|
||||
query$.pipe(distinctUntilKeyChanged("value")),
|
||||
index$
|
||||
.pipe(
|
||||
map(({ icons, emojis }) => [
|
||||
...Object.keys(icons.data),
|
||||
...Object.keys(emojis.data)
|
||||
combineLatestWith(mode$),
|
||||
map(([{ icons, emojis }, mode]) => [
|
||||
...["all", "icons"].includes(mode)
|
||||
? Object.keys(icons.data)
|
||||
: [],
|
||||
...["all", "emojis"].includes(mode)
|
||||
? Object.keys(emojis.data)
|
||||
: []
|
||||
])
|
||||
)
|
||||
])
|
||||
@@ -169,7 +177,7 @@ export function watchIconSearchResult(
|
||||
* @returns Icon search result component observable
|
||||
*/
|
||||
export function mountIconSearchResult(
|
||||
el: HTMLElement, { index$, query$ }: MountOptions
|
||||
el: HTMLElement, { index$, query$, mode$ }: MountOptions
|
||||
): Observable<Component<IconSearchResult, HTMLElement>> {
|
||||
const push$ = new Subject<IconSearchResult>()
|
||||
const boundary$ = watchElementBoundary(el)
|
||||
@@ -178,7 +186,7 @@ export function mountIconSearchResult(
|
||||
)
|
||||
|
||||
/* Update search result metadata */
|
||||
const meta = getElement(":scope > :first-child", el)
|
||||
const meta = getElement(".mdx-iconsearch-result__meta", el)
|
||||
push$
|
||||
.pipe(
|
||||
withLatestFrom(query$)
|
||||
@@ -228,7 +236,7 @@ export function mountIconSearchResult(
|
||||
))
|
||||
|
||||
/* Create and return component */
|
||||
return watchIconSearchResult(el, { query$, index$ })
|
||||
return watchIconSearchResult(el, { query$, index$, mode$ })
|
||||
.pipe(
|
||||
tap(state => push$.next(state)),
|
||||
finalize(() => push$.complete()),
|
||||
|
||||
@@ -90,6 +90,38 @@
|
||||
right: px2rem(12px);
|
||||
font-size: px2rem(12.8px);
|
||||
color: var(--md-default-fg-color--lighter);
|
||||
|
||||
// [mobile portrait -]: Hide meta
|
||||
@include break-to-device(mobile portrait) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Icon search result select
|
||||
&__select {
|
||||
position: absolute;
|
||||
top: px2rem(8px);
|
||||
right: px2rem(12px);
|
||||
padding-block: 0.15em;
|
||||
font-size: px2rem(12.8px);
|
||||
color: var(--md-default-fg-color--light);
|
||||
background-color: var(--md-default-fg-color--lightest);
|
||||
border: none;
|
||||
border-radius: px2rem(2px);
|
||||
transition: color 125ms, background-color 125ms;
|
||||
|
||||
// Focused or hovered
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: var(--md-accent-bg-color);
|
||||
background-color: var(--md-accent-fg-color);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// Adjust spacing
|
||||
+ .mdx-iconsearch-result__meta {
|
||||
right: px2rem(82px);
|
||||
}
|
||||
}
|
||||
|
||||
// Icon search result list
|
||||
|
||||
Reference in New Issue
Block a user