import filterAlteredClicks from 'filter-altered-clicks'; import md5 from 'md5'; import React, { HTMLAttributes } from 'react'; import { version as VERSION } from '../package.json'; import { useGraph, useModule, usePane, useQuery } from './App'; import { selectTag } from './Graph'; import GraphPane from './GraphPane'; import InfoPane from './InfoPane'; import ModulePane from './ModulePane'; import { tagify } from './util'; import '/css/Inspector.scss'; export function Fix() { return FIX!; } export function ExternalLink({ href, children, target = '_blank', className, ...props }: { className?: string } & HTMLAttributes) { return ( {children} open_in_new ); } export function QueryLink({ query }) { const [, setQuery] = useQuery(); if (!Array.isArray(query)) query = [query]; function onClick(e) { e.preventDefault(); setQuery(query); history.pushState(null, null, e.target.href); } const url = new URL(location.href); url.search = query.length ? `q=${query.join(',')}` : ''; return ( {query.join(',')} ); } export function Section({ title, children, open = true, }: { title: string; open: boolean } & HTMLAttributes) { return ( {title || 'Untitled'} {children} ); } export function Pane({ children, ...props }: HTMLAttributes) { return ( {children} ); } export function Tags({ children, style, ...props }: HTMLAttributes) { return ( {children} ); } export function Tag({ type, name, title = name, count = 0, gravatar, className, }: { type: string; name: string; title: string; count: number; gravatar: string; } & HTMLAttributes) { if (count > 1) title += ` (${count})`; let img = null; if (gravatar) { const hash = md5(gravatar); img = ; } return ( selectTag(tagify(type, name), true, true)} > {img} {title} ); } function Tab({ active, children, ...props }: HTMLAttributes) { return ( {children} ); } export default function Inspector(props) { const [query, setQuery] = useQuery(); const [pane, setPane] = usePane(); const [module] = useModule(); const [graph] = useGraph(); let paneComponent; switch (pane) { case 'module': paneComponent = ; break; case 'graph': paneComponent = ; break; case 'info': paneComponent = ; break; } function doSearch(e: React.KeyboardEvent) { const names = (e.currentTarget as HTMLInputElement).value .split(',') .map(v => v.trim()) .filter(Boolean); const query = [...new Set(names)]; // De-dupe // Update location const url = new URL(location.href); url.hash = ''; query.length ? url.searchParams.set('q', query.join(',')) : url.searchParams.delete('q'); history.replaceState(null, document.title, url); setQuery(query); } return ( setPane('module')}> Module setPane('graph')}> Graph setPane('info')}> {'\u{24d8}'} { if (/^(?:Enter|Tab)$/.test(e.key)) doSearch(e); }} placeholder={'\u{1F50D} \xa0Enter module name'} autoFocus /> {paneComponent} ); }