diff options
| author | 2023-12-15 09:11:47 +0800 | |
|---|---|---|
| committer | 2023-12-15 09:11:47 +0800 | |
| commit | be8de118db913711eb72ae5187d26e54a0055727 (patch) | |
| tree | 96cd6c012dafa3f4015e54edef90df5eaaab0ddb /src/overrides/assets/javascripts/components/iconsearch | |
| parent | 9b2d27ba1d91a0d5531bc9c0d52c3887a2dfb2aa (diff) | |
| download | infini-be8de118db913711eb72ae5187d26e54a0055727.tar.gz infini-be8de118db913711eb72ae5187d26e54a0055727.zip | |
refactor(docs): optmst `docs` dir & `deps`
Diffstat (limited to 'src/overrides/assets/javascripts/components/iconsearch')
4 files changed, 0 insertions, 452 deletions
diff --git a/src/overrides/assets/javascripts/components/iconsearch/_/index.ts b/src/overrides/assets/javascripts/components/iconsearch/_/index.ts deleted file mode 100644 index f509a6f9..00000000 --- a/src/overrides/assets/javascripts/components/iconsearch/_/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, merge } from "rxjs" - -import { configuration } from "~/_" -import { requestJSON } from "~/browser" - -import { Component, getComponentElement } from "../../_" -import { - IconSearchQuery, - mountIconSearchQuery -} from "../query" -import { - IconSearchResult, - mountIconSearchResult -} from "../result" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon category - */ -export interface IconCategory { - base: string /* Category base URL */ - data: Record<string, string> /* Category data */ -} - -/** - * Icon search index - */ -export interface IconSearchIndex { - icons: IconCategory /* Icons */ - emojis: IconCategory /* Emojis */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Icon search - */ -export type IconSearch = - | IconSearchQuery - | IconSearchResult - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search - * - * @param el - Icon search element - * - * @returns Icon search component observable - */ -export function mountIconSearch( - el: HTMLElement -): Observable<Component<IconSearch>> { - const config = configuration() - const index$ = requestJSON<IconSearchIndex>( - new URL("assets/javascripts/iconsearch_index.json", config.base) - ) - - /* Retrieve query and result components */ - const query = getComponentElement("iconsearch-query", el) - const result = getComponentElement("iconsearch-result", el) - - /* Create and return component */ - const query$ = mountIconSearchQuery(query) - const result$ = mountIconSearchResult(result, { index$, query$ }) - return merge(query$, result$) -} diff --git a/src/overrides/assets/javascripts/components/iconsearch/index.ts b/src/overrides/assets/javascripts/components/iconsearch/index.ts deleted file mode 100644 index 9d856774..00000000 --- a/src/overrides/assets/javascripts/components/iconsearch/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./query" -export * from "./result" diff --git a/src/overrides/assets/javascripts/components/iconsearch/query/index.ts b/src/overrides/assets/javascripts/components/iconsearch/query/index.ts deleted file mode 100644 index 03a3daad..00000000 --- a/src/overrides/assets/javascripts/components/iconsearch/query/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - combineLatest, - delay, - distinctUntilChanged, - filter, - fromEvent, - map, - merge, - startWith, - withLatestFrom -} from "rxjs" - -import { watchElementFocus } from "~/browser" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search query - */ -export interface IconSearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search query - * - * @param el - Icon search query element - * - * @returns Icon search query component observable - */ -export function mountIconSearchQuery( - el: HTMLInputElement -): Observable<Component<IconSearchQuery, HTMLInputElement>> { - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)) - ) - .pipe( - map(() => el.value), - startWith(el.value), - distinctUntilChanged(), - ) - - /* Log search on blur */ - focus$ - .pipe( - filter(active => !active), - withLatestFrom(value$) - ) - .subscribe(([, value]) => { - const path = document.location.pathname - if (typeof ga === "function" && value.length) - ga("send", "pageview", `${path}?q=[icon]+${value}`) - }) - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ ref: el, value, focus })), - ) -} diff --git a/src/overrides/assets/javascripts/components/iconsearch/result/index.ts b/src/overrides/assets/javascripts/components/iconsearch/result/index.ts deleted file mode 100644 index 2b9d97fb..00000000 --- a/src/overrides/assets/javascripts/components/iconsearch/result/index.ts +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { filter as search } from "fuzzaldrin-plus" -import { - Observable, - Subject, - bufferCount, - combineLatest, - distinctUntilKeyChanged, - filter, - finalize, - map, - merge, - of, - switchMap, - tap, - withLatestFrom, - zipWith -} from "rxjs" - -import { - getElement, - watchElementBoundary -} from "~/browser" -import { round } from "~/utilities" - -import { Icon, renderIconSearchResult } from "_/templates" - -import { Component } from "../../_" -import { IconSearchIndex } from "../_" -import { IconSearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search result - */ -export interface IconSearchResult { - data: Icon[] /* Search result data */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - index$: Observable<IconSearchIndex> /* Search index observable */ - query$: Observable<IconSearchQuery> /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - index$: Observable<IconSearchIndex> /* Search index observable */ - query$: Observable<IconSearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch icon search result - * - * @param el - Icon search result element - * @param options - Options - * - * @returns Icon search result observable - */ -export function watchIconSearchResult( - el: HTMLElement, { index$, query$ }: WatchOptions -): Observable<IconSearchResult> { - 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("") - } - }) - })) - )) - ) - } -} - -/** - * Mount icon search result - * - * @param el - Icon search result element - * @param options - Options - * - * @returns Icon search result component observable - */ -export function mountIconSearchResult( - el: HTMLElement, { index$, query$ }: MountOptions -): Observable<Component<IconSearchResult, HTMLElement>> { - const push$ = new Subject<IconSearchResult>() - const boundary$ = watchElementBoundary(el) - .pipe( - filter(Boolean) - ) - - /* Update search result metadata */ - const meta = getElement(":scope > :first-child", el) - push$ - .pipe( - withLatestFrom(query$) - ) - .subscribe(([{ data }, { value }]) => { - if (value) { - switch (data.length) { - - /* No results */ - case 0: - meta.textContent = "No matches" - break - - /* One result */ - case 1: - meta.textContent = "1 match" - break - - /* Multiple result */ - default: - meta.textContent = `${round(data.length)} matches` - } - } else { - 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( - tap(() => list.innerHTML = ""), - switchMap(({ data }) => merge( - of(...data.slice(0, 10)), - of(...data.slice(10)) - .pipe( - bufferCount(10), - zipWith(boundary$), - switchMap(([chunk]) => chunk) - ) - )), - withLatestFrom(query$) - ) - .subscribe(([result, { value }]) => list.appendChild( - renderIconSearchResult(result, value, file) - )) - - /* Create and return component */ - return watchIconSearchResult(el, { query$, index$ }) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) -} |
