1- import { useState , useCallback , useRef , useEffect , type ReactNode } from "react" ;
21import {
3- Duckling ,
4- type RenderMapFn ,
5- } from "@claudiu-ceia/ts-duckling" ;
2+ type ReactNode ,
3+ useCallback ,
4+ useEffect ,
5+ useRef ,
6+ useState ,
7+ } from "react" ;
8+ import { Duckling , type RenderMapFn } from "@claudiu-ceia/ts-duckling" ;
69import { Header } from "./components/Header" ;
710import { ParserSidebar } from "./components/ParserSidebar" ;
811import { AnnotatedText } from "./components/AnnotatedText" ;
912import { Hovercard } from "./components/Hovercard" ;
1013import { extract , type ExtractResult } from "./extract-client" ;
1114import type { EntityResult } from "./types" ;
12- import { PARSER_PRIORITY , PRESETS , ALL_IDS } from "./registry" ;
13- import { fmtDuration , loadSelection , saveSelection , kindClasses } from "./utils" ;
15+ import { ALL_IDS , PARSER_PRIORITY , PRESETS } from "./registry" ;
16+ import {
17+ fmtDuration ,
18+ kindClasses ,
19+ loadSelection ,
20+ saveSelection ,
21+ } from "./utils" ;
1422import { loadUrlText } from "./fetch-url" ;
1523import { registry } from "./parsers" ;
1624
@@ -29,8 +37,12 @@ export function App() {
2937 const [ url , setUrl ] = useState ( "" ) ;
3038 const [ loading , setLoading ] = useState ( false ) ;
3139
32- const [ hovercardEntities , setHovercardEntities ] = useState < EntityResult [ ] > ( [ ] ) ;
33- const [ hovercardAnchor , setHovercardAnchor ] = useState < HTMLElement | null > ( null ) ;
40+ const [ hovercardEntities , setHovercardEntities ] = useState < EntityResult [ ] > (
41+ [ ] ,
42+ ) ;
43+ const [ hovercardAnchor , setHovercardAnchor ] = useState < HTMLElement | null > (
44+ null ,
45+ ) ;
3446
3547 const abortRef = useRef < AbortController | null > ( null ) ;
3648 const timerRef = useRef < ReturnType < typeof setTimeout > > ( undefined ) ;
@@ -69,7 +81,11 @@ export function App() {
6981 return (
7082 < span
7183 key = { `${ entity . start } -${ entity . end } -${ entity . kind } ` }
72- className = { `ent relative cursor-pointer rounded-md px-1 py-0.5 text-slate-900 outline-1 ${ kindClasses ( entity . kind ) } ${ hasChildren ? " border-b-2 border-dashed border-slate-400/40" : "" } ` }
84+ className = { `ent relative cursor-pointer rounded-md px-1 py-0.5 text-slate-900 outline-1 ${
85+ kindClasses ( entity . kind )
86+ } ${
87+ hasChildren ? " border-b-2 border-dashed border-slate-400/40" : ""
88+ } `}
7389 onClick = { ( ev : React . MouseEvent < HTMLSpanElement > ) => {
7490 ev . stopPropagation ( ) ;
7591 // Show all entities contained within this span
@@ -149,9 +165,7 @@ export function App() {
149165 if ( controller . signal . aborted ) return ;
150166
151167 setSegments ( segs ) ;
152- const suffix = result . truncated
153- ? ` (prefix ${ result . length } chars)`
154- : "" ;
168+ const suffix = result . truncated ? ` (prefix ${ result . length } chars)` : "" ;
155169 setTiming ( `${ fmtDuration ( result . ms ) } ${ suffix } ` ) ;
156170 setStatus ( "" ) ;
157171 } catch ( err ) {
@@ -263,19 +277,28 @@ export function App() {
263277
264278 < main className = "mx-auto max-w-7xl px-6 py-6" >
265279 < div className = "grid grid-cols-1 gap-4 lg:grid-cols-[360px_1fr]" >
266- < ParserSidebar selected = { selected } onSelectionChange = { onSelectionChange } />
280+ < ParserSidebar
281+ selected = { selected }
282+ onSelectionChange = { onSelectionChange }
283+ />
267284
268285 < div className = "space-y-4" >
269286 { /* Input section */ }
270287 < section className = "rounded-2xl border border-slate-200 bg-white shadow-sm" >
271288 < div className = "flex items-center justify-between border-b border-slate-200 px-4 py-3" >
272- < h2 className = "text-sm font-semibold tracking-wide text-slate-900" > Input</ h2 >
273- < div className = "text-sm text-slate-500" > { input . length } chars</ div >
289+ < h2 className = "text-sm font-semibold tracking-wide text-slate-900" >
290+ Input
291+ </ h2 >
292+ < div className = "text-sm text-slate-500" >
293+ { input . length } chars
294+ </ div >
274295 </ div >
275296 < div className = "p-4" >
276297 < div className = "grid grid-cols-1 gap-3 md:grid-cols-[160px_1fr]" >
277298 < label className = "text-sm text-slate-600" >
278- < div className = "mb-1 font-medium text-slate-700" > Preset</ div >
299+ < div className = "mb-1 font-medium text-slate-700" >
300+ Preset
301+ </ div >
279302 < select
280303 value = { preset }
281304 onChange = { ( e ) => handlePreset ( e . target . value ) }
@@ -289,14 +312,17 @@ export function App() {
289312 </ label >
290313
291314 < div >
292- < div className = "mb-1 text-sm font-medium text-slate-700" > Max chars</ div >
315+ < div className = "mb-1 text-sm font-medium text-slate-700" >
316+ Max chars
317+ </ div >
293318 < div className = "flex items-center gap-2" >
294319 < input
295320 type = "number"
296321 min = { 500 }
297322 step = { 500 }
298323 value = { maxChars }
299- onChange = { ( e ) => setMaxChars ( Number ( e . target . value ) || 8000 ) }
324+ onChange = { ( e ) =>
325+ setMaxChars ( Number ( e . target . value ) || 8000 ) }
300326 className = "w-32 rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm font-semibold text-slate-900 shadow-sm focus:border-teal-300 focus:outline-none focus:ring-4 focus:ring-teal-200/40"
301327 />
302328 < label className = "flex items-center gap-2 text-sm font-medium text-slate-700" >
@@ -319,7 +345,9 @@ export function App() {
319345 type = "text"
320346 value = { url }
321347 onChange = { ( e ) => setUrl ( e . target . value ) }
322- onKeyDown = { ( e ) => { if ( e . key === "Enter" ) handleLoadUrl ( ) ; } }
348+ onKeyDown = { ( e ) => {
349+ if ( e . key === "Enter" ) handleLoadUrl ( ) ;
350+ } }
323351 placeholder = "https://en.wikipedia.org/wiki/Perceptual_hashing"
324352 className = "w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm font-medium text-slate-900 shadow-sm placeholder:text-slate-400 focus:border-teal-300 focus:outline-none focus:ring-4 focus:ring-teal-200/40"
325353 />
@@ -336,7 +364,10 @@ export function App() {
336364
337365 < textarea
338366 value = { input }
339- onChange = { ( e ) => { setInput ( e . target . value ) ; setPreset ( "" ) ; } }
367+ onChange = { ( e ) => {
368+ setInput ( e . target . value ) ;
369+ setPreset ( "" ) ;
370+ } }
340371 disabled = { spinning }
341372 spellCheck = { false }
342373 className = "mt-4 h-56 w-full resize-y rounded-2xl border border-slate-200 bg-white p-4 font-mono text-sm leading-relaxed text-slate-900 shadow-sm focus:border-teal-300 focus:outline-none focus:ring-4 focus:ring-teal-200/40 disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed"
@@ -348,13 +379,17 @@ export function App() {
348379 { /* Preview section */ }
349380 < section className = "rounded-2xl border border-slate-200 bg-white shadow-sm" >
350381 < div className = "flex items-center justify-between border-b border-slate-200 px-4 py-3" >
351- < h2 className = "text-sm font-semibold tracking-wide text-slate-900" > Preview</ h2 >
382+ < h2 className = "text-sm font-semibold tracking-wide text-slate-900" >
383+ Preview
384+ </ h2 >
352385 < div className = "flex items-center gap-3 text-sm text-slate-500" >
353386 < span > { entities . length } matches</ span >
354387 { elapsed && (
355388 < >
356389 < span className = "text-slate-300" > •</ span >
357- < span className = "font-mono text-teal-600 tabular-nums" > { elapsed } </ span >
390+ < span className = "font-mono text-teal-600 tabular-nums" >
391+ { elapsed }
392+ </ span >
358393 </ >
359394 ) }
360395 { timing && ! elapsed && (
@@ -379,7 +414,9 @@ export function App() {
379414 Annotated text
380415 </ div >
381416 < div className = "mt-2" >
382- < AnnotatedText segments = { segments . length > 0 ? segments : [ input ] } />
417+ < AnnotatedText
418+ segments = { segments . length > 0 ? segments : [ input ] }
419+ />
383420 </ div >
384421
385422 { showJson && (
@@ -401,7 +438,10 @@ export function App() {
401438 < Hovercard
402439 entities = { hovercardEntities }
403440 anchor = { hovercardAnchor }
404- onClose = { ( ) => { setHovercardEntities ( [ ] ) ; setHovercardAnchor ( null ) ; } }
441+ onClose = { ( ) => {
442+ setHovercardEntities ( [ ] ) ;
443+ setHovercardAnchor ( null ) ;
444+ } }
405445 />
406446 </ >
407447 ) ;
0 commit comments