A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/signumsoftware/framework/commit/fbba1e4e124a610bdf7b90afd81f681cb00566a0 below:

Highlighting in SearchControl · signumsoftware/framework@fbba1e4 · GitHub

@@ -13,7 +13,7 @@ export interface TypeaheadProps {

13 13

itemsDelay?: number;

14 14

minLength?: number;

15 15

renderList?: (typeahead: TypeaheadController) => React.ReactNode;

16 -

renderItem?: (item: unknown, query: string) => React.ReactNode;

16 +

renderItem?: (item: unknown, highlighter: TextHighlighter) => React.ReactNode;

17 17

onSelect?: (item: unknown, e: React.KeyboardEvent<any> | React.MouseEvent<any>) => string | null;

18 18

scrollHeight?: number;

19 19

inputAttrs?: React.InputHTMLAttributes<HTMLInputElement>;

@@ -257,6 +257,8 @@ export const Typeahead = React.forwardRef(function Typeahead(p: TypeaheadProps,

257 257 258 258

function renderDefaultList() {

259 259

var items = controller.items;

260 + 261 +

var highlighter = TextHighlighter.fromString(controller.query);

260 262

return (

261 263

<Dropdown.Menu align={controller.rtl ? "end" : undefined} className="typeahead">

262 264

{

@@ -268,7 +270,7 @@ export const Typeahead = React.forwardRef(function Typeahead(p: TypeaheadProps,

268 270

onMouseLeave={e => controller.handleElementMouseLeave(e, i)}

269 271

onMouseUp={e => controller.handleMenuMouseUp(e, i)}

270 272

{...p.itemAttrs && p.itemAttrs(item)}>

271 -

{p.renderItem!(item, controller.query!)}

273 +

{p.renderItem!(item, highlighter)}

272 274

</button>)

273 275

}

274 276

</Dropdown.Menu>

@@ -293,7 +295,7 @@ Typeahead.defaultProps = {

293 295

getItems: undefined as any,

294 296

itemsDelay: 200,

295 297

minLength: 1,

296 -

renderItem: (item, query) => TypeaheadOptions.highlightedText(item as string, query),

298 +

renderItem: (item, highlighter) => highlighter.highlight(item as string),

297 299

onSelect: (elem, event) => (elem as string),

298 300

scrollHeight: 0,

299 301

@@ -302,57 +304,55 @@ Typeahead.defaultProps = {

302 304 303 305 304 306

export namespace TypeaheadOptions {

305 -

export function highlightedText(val: string, query?: string): React.ReactChild {

306 307 307 -

if (query == undefined)

308 -

return val;

308 +

export function normalizeString(str: string): string {

309 +

return str;

310 +

}

311 +

}

309 312 310 -

const index = val.toLowerCase().indexOf(query.toLowerCase());

311 -

if (index == -1)

312 -

return val;

313 +

export class TextHighlighter {

314 +

query?: string;

315 +

parts?: string[];

316 +

regex?: RegExp;

313 317 314 -

return (

315 -

<>

316 -

{val.substr(0, index)}

317 -

<strong key={0}>{val.substr(index, query.length)}</strong>

318 -

{val.substr(index + query.length)}

319 -

</>

320 -

);

318 +

static fromString(query: string | undefined) {

319 +

var hl = new TextHighlighter(query?.split(" "));

320 +

hl.query = query;

321 +

return hl;

321 322

}

322 323 323 -

export function highlightedTextAll(val: string, query: string | undefined): React.ReactChild {

324 -

if (query == undefined)

325 -

return val;

324 +

constructor(parts: string[] | undefined) {

325 +

this.parts = parts?.filter(a => a != null && a.length > 0).orderByDescending(a => a.length);

326 +

if (this.parts?.length)

327 +

this.regex = new RegExp(this.parts.map(p => RegExp.escape(p)).join("|"), "gi");

328 +

}

326 329 327 -

const parts = query.toLocaleLowerCase().split(" ").filter(a => a.length > 0).orderByDescending(a => a.length);

330 +

highlight(text: string): React.ReactChild {

331 +

if (!text || !this.regex)

332 +

return text;

328 333 329 -

function splitText(str: string, partIndex: number): React.ReactChild {

334 +

var matches = Array.from(text.matchAll(this.regex));

330 335 331 -

if (str.length == 0)

332 -

return str;

336 +

if (matches.length == 0)

337 +

return text;

333 338 334 -

if (parts.length <= partIndex)

335 -

return str;

339 +

var result = [];

336 340 337 -

var part = parts[partIndex];

341 +

var pos = 0;

342 +

for (var i = 0; i < matches.length; i++) {

343 +

var m = matches[i];

338 344 339 -

const index = str.toLowerCase().indexOf(part);

340 -

if (index == -1)

341 -

return splitText(str, partIndex + 1);

345 +

if (pos < m.index!) {

346 +

result.push(text.substring(pos, m.index));

347 +

}

342 348 343 -

return (

344 -

<>

345 -

{splitText(str.substr(0, index), partIndex + 1)}

346 -

<strong key={0}>{str.substr(index, part.length)}</strong>

347 -

{splitText(str.substr(index + part.length), partIndex + 1)}

348 -

</>

349 -

);

349 +

pos = m.index! + m[0].length;

350 +

result.push(<strong>{text.substring(m.index!, pos)}</strong>);

350 351

}

351 352 352 -

return splitText(val, 0);

353 -

}

353 +

if (pos < text.length)

354 +

result.push(text.substring(pos));

354 355 355 -

export function normalizeString(str: string): string {

356 -

return str;

356 +

return React.createElement(React.Fragment, undefined, ...result);

357 357

}

358 358

}


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4