{"id":13341403,"url":"https://github.com/sskanishk/search-box","last_synced_at":"2025-03-11T21:30:56.336Z","repository":{"id":39650382,"uuid":"497195009","full_name":"sskanishk/search-box","owner":"sskanishk","description":"This is a simple search filter build in react which show the result based matched data field. It is designed by keeping web accessibility in mind where user can navigate result view using keyboard up down key.","archived":false,"fork":false,"pushed_at":"2022-12-02T13:46:55.000Z","size":475,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-24T08:30:21.151Z","etag":null,"topics":["react","web-accessibility"],"latest_commit_sha":null,"homepage":"https://searchboxfilter.netlify.app/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sskanishk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-28T02:47:26.000Z","updated_at":"2023-07-18T09:13:05.000Z","dependencies_parsed_at":"2022-09-20T06:51:23.158Z","dependency_job_id":null,"html_url":"https://github.com/sskanishk/search-box","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskanishk%2Fsearch-box","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskanishk%2Fsearch-box/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskanishk%2Fsearch-box/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sskanishk%2Fsearch-box/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sskanishk","download_url":"https://codeload.github.com/sskanishk/search-box/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243115314,"owners_count":20238738,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","web-accessibility"],"created_at":"2024-07-29T19:25:25.870Z","updated_at":"2025-03-11T21:30:56.072Z","avatar_url":"https://github.com/sskanishk.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Search Box\n\nThis is a simple search filter build in react which show the result based matched data field. \nIt is designed by keeping web accessibility in mind where user can navigate result view using keyboard up down key.\n\n## Deveopment Setup\n```\nnpm install\nnpm run dev\n```\n\n## Features\n\n\n### Automatically focus on input filed as the page load this is achieved using useRef.\n`\u003cinput ref={inputRef}\u003e` \nAfter the page render or the first time you will get the access to the input field. In the useEffect `inputRef.current.focus()` is placed and adding empty array to avoid unnecessary rendering.\n\n\n### Added eventListener to listen keyboard events.\nBy taking advantage of useEffect added `onkeydown` event over body, so if someone use keyboard can be track accordingly actions can be trigger.\nWhen the page mount eventListener are added by as we switch to anothet page i.e. unmount listener are still waiting for event, so to remove unwanted listener - returning new function from useEffect which remove them.\n```jsx\n    useEffect(() =\u003e {\n        if (data.length \u003e 0) {\n            document.body.addEventListener('keydown', onKeyDown)\n            document.body.addEventListener('mousemove', onMouseMove)\n        } else {\n            document.body.removeEventListener('keydown', onKeyDown)\n        }\n        return () =\u003e {\n            document.body.removeEventListener('keydown', onKeyDown)\n            document.body.removeEventListener('mousemove', onMouseMove)\n        }\n    }, [data])\n```\n\n### Trigger action when key are pressed to navigate card in result view.\nBackspace, ArrowUp and ArrowDown these are the three case where action is trigger.\nOnKeyDown trigger and `event.code` show which key is trigger based on that we navigate the result view.\n```jsx\n    const onKeyDown = (event) =\u003e {\n\n        const isInputFocused = document.activeElement === inputRef.current\n        const resultItems = Array.from(resultRef.current.children)\n\n        const activeResultIndex = resultItems.findIndex(child =\u003e {\n            return child.querySelector('a') === document.activeElement\n        })\n\n        if (event.key === 'ArrowUp') {\n            if (isInputFocused) {\n                resultItems[resultItems.length - 1].querySelector('a').focus();\n            } else if (resultItems[activeResultIndex - 1]) {\n                resultItems[activeResultIndex - 1].querySelector('a').focus();\n            } else {\n                inputRef.current.focus();\n            }\n        }\n\n        if (event.key === 'ArrowDown') {\n            if (isInputFocused) {\n                resultItems[0].querySelector('a').focus();\n            } else if (resultItems[activeResultIndex + 1]) {\n                resultItems[activeResultIndex + 1].querySelector('a').focus();\n            } else {\n                inputRef.current.focus();\n            }\n        }\n\n        if (event.key === 'Backspace') {\n            inputRef.current.focus();\n        }\n    }\n```\nSimilary the `onMouseMove` trigger which remove the focus from xyz card in result view beacuse keyboard will take preference if mouse is kept hovered on the list, similarly mouse will take preference if keyboard navigation is not used.\n```jsx\n    const onMouseMove = () =\u003e {\n        inputRef.current.focus()\n    }\n```\n### Highlight match string in the card of result view.\nTo get the highligted string in result im using below function which take text, string which eneter in the input field, id(used as key in map) and style.\nUsed RegExp whith [gi(global and insensitive)](https://stackoverflow.com/a/27916097/7816309) modifier which split the text in matched and unmatched string. Return matched string with some color or css style and unmatched. btw position of the string are untouched.\n```jsx\n    const getHighlightedText = (text, highlight, id, style) =\u003e {\n        const parts = text?.split(new RegExp(`(${highlight})`, 'gi'));\n        if (!parts) return text\n        return \u003cspan style={style}\u003e {parts.map((part, i) =\u003e {\n            return \u003cspan key={`${id}${i}`} style={part.toLowerCase() === highlight.toLowerCase() ? { color: 'blueviolet', textDecoration: 'underline' } : {}}\u003e\n                {part}\n            \u003c/span\u003e\n        })} \u003c/span\u003e;\n    }\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsskanishk%2Fsearch-box","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsskanishk%2Fsearch-box","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsskanishk%2Fsearch-box/lists"}