{"_id":"@academix-admin/search-viewer","_rev":"8-814011252ae0cc4fb9ddc5d7f06d7b2c","name":"@academix-admin/search-viewer","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@academix-admin/search-viewer","version":"0.1.0","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.1.0","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"e04f68a21c157e2aa25afb1627bfeac116a0dae0","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.1.0.tgz","fileCount":9,"integrity":"sha512-7ucUXIt3MI7WifYp/qz53xkReJbNTXlx0IfxQ70td2GTzWQmf1jgG/vpEUchd2jR3EtbWrKZMRQwDe0Och5I8Q==","signatures":[{"sig":"MEQCIAROZlvC5s7ef8VT+LpTLCdMzlQODNORvzXlDYMXZ8OuAiA+B/3kt0adAokbkC9GHPY/20XwovrHwFtvdE/suf4CDg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":262614},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"22fcc5fea088a5b2c708d09013f62309af1e9b79","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React — debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.1.0_1784657079737_0.5806794026806621","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@academix-admin/search-viewer","version":"0.1.1","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.1.1","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"a01f7c10ad6d9c4259d71a517abfb3c9d37907c1","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.1.1.tgz","fileCount":9,"integrity":"sha512-pAnmWL2WtiT+LhJqWGAN7qgQy9lG9oUqNw2YZslZH66rcDAsplP0K3RaMrcRyYYQ3gq6Kwi485Z3+gJRnRsaaQ==","signatures":[{"sig":"MEYCIQDSILrcC5avr3Nh3aqyv5vHET7p1PBBh9LdpqJrwtMvUgIhAJyAmaOG4xTOajJsTLhgBQMKGhg7tn2eUqipnDfGZ1UG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":270036},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"10a2249ee15eac0b92de67b3e9b694ab8deb48e5","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React — debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.1.1_1785602084923_0.9082070832882485","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@academix-admin/search-viewer","version":"0.1.2","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.1.2","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"c7addd754f772db14316a02d449cae5f56959afd","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.1.2.tgz","fileCount":9,"integrity":"sha512-18yNFxvTOmpsbIj+lzaMqLzfaf2y377qLAJ3hfERFyqyMPzVlv0HbPiEgpjjjxOV9rRB/fgSLk1sZTIckyBCBg==","signatures":[{"sig":"MEUCIAERVOJtfRB6LSz/DeCPfmGi469YeOQUGVyP00tOYdPmAiEAgxlfOoERxstRI9LztPwVF3zQhDyX8+hbPhTtThNTz+0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":272517},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"f459f9b41f9947f6f66e3b62a1aa061ef293bdad","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React — debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.1.2_1785754502313_0.6671679859642421","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@academix-admin/search-viewer","version":"0.1.3","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.1.3","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"e8724ea66531786ff0676f88624c78d6bfecfd8f","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.1.3.tgz","fileCount":9,"integrity":"sha512-VXkdIFJLSnU5ekOzNSxCkw6oW3+CuXzW9hrhOi71PeXvf7Rj7z+Svl9ncbOT2LzkiOR7LO5Zf6LRDocEQqHqXg==","signatures":[{"sig":"MEUCIQDZ/cxC5SqspQhW7iCeepk/pJq205dj6RBAxMBxurXBHgIgJNHAKVyZNHipQPYmV8WgpJKvL2EnksrRusLckvgypOo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":282514},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"ea6dd30969c12edb50817f71322b6137476bbed0","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React â€” debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.1.3_1785906847440_0.8919155319935075","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@academix-admin/search-viewer","version":"0.1.4","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.1.4","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"ace18d1224d6982b52cdb52d879263ef094d840c","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.1.4.tgz","fileCount":9,"integrity":"sha512-W0fJYgn4OTbScvRQABRawT9k4VGrEqkjvMNrJzA996MVYreNSz7VTgDs7nfZv1tkr0J4sExFucGQH3cpLcYS0Q==","signatures":[{"sig":"MEQCIALE3ejlAkrO/Q9OqzZCXHxhwwlO9bjUia7cBab8jPIoAiBwZL4UHSipwUUGfu0lbfM1obx18uqBIRMpYWilb1tAvw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":283458},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"7477a8b3623987f82d9c330463768f7d966f86e0","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React â€” debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.1.4_1785922214264_0.9194278149360207","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@academix-admin/search-viewer","version":"0.2.0","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.2.0","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"8fe9ee93d2169ac86f6a86ebdee9602a7be33fbd","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.2.0.tgz","fileCount":9,"integrity":"sha512-L8bG4SlLLsZ713+7eYz9lWPR4CkfGSX7nr+vYfgvWpFUj/wIsEFEUztd14AF0ytrR3x8PevSeoJz9fDK80Q42Q==","signatures":[{"sig":"MEYCIQDj+SiKnKuIAXZUsdqUBBo8DHSU3wHbBisRerR8LZDR0gIhAMryZPByPH0Uw8ETeYo2uZHQ90Rr02iPRwsTZJTr8qmj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":278850},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"23643577d35b66286e0aa3ee2bc574b0690f8185","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React â€” debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.2.0_1786143913011_0.4168981134643932","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@academix-admin/search-viewer","version":"0.2.1","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"author":{"name":"Academix"},"license":"MIT","_id":"@academix-admin/search-viewer@0.2.1","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"dist":{"shasum":"e0df01c1b2f26dd9861c92da40dec0306414582e","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.2.1.tgz","fileCount":9,"integrity":"sha512-LAd0DLkbZfH0V6rJmuz6oBb95cMVmKaar18Nc7Zj19uDyaas0T5my/EuRwSklP7/q2XjfCzVPIi1gC9Z96ZZqg==","signatures":[{"sig":"MEYCIQD4c+RD2i2AGmFoOuQr28U3xnIVzVEZSk/9VnzZUrYdKwIhAPzVPI3876H09sMeFpfiWij8Lx3G8rezRSSHHFGqsrnt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295643},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"gitHead":"2fb8e01f6ea7d41bf480d058a8c99b32dd2e53cb","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rimraf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"repository":{"url":"git+https://github.com/academix-admin/academix-ui.git","type":"git","directory":"packages/search-viewer"},"_npmVersion":"11.13.0","description":"Headless-friendly search & selection UI for React â€” debounced controller, single/multi select, and sheet-based pickers.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","react":"^18.3.1","motion":"^12.23.24","rimraf":"^6.0.1","react-dom":"^18.3.1","typescript":"^5.9.3","@types/react":"^19.0.0","@types/react-dom":"^19.0.0"},"peerDependencies":{"react":">=18.0.0","motion":">=11.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search-viewer_0.2.1_1787524890157_0.5813177090025614","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@academix-admin/search-viewer","version":"0.3.0","description":"Headless-friendly search & selection UI for React â€” debounced controller, single/multi select, and sheet-based pickers.","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"license":"MIT","author":{"name":"Academix"},"repository":{"type":"git","url":"git+https://github.com/academix-admin/academix-ui.git","directory":"packages/search-viewer"},"homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"type":"module","sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"scripts":{"build":"tsup","clean":"rimraf dist","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit"},"dependencies":{"@academix-admin/modal-sheet":"^0.1.0"},"peerDependencies":{"motion":">=11.0.0","react":">=18.0.0","react-dom":">=18.0.0"},"devDependencies":{"@types/react":"^19.0.0","@types/react-dom":"^19.0.0","motion":"^12.23.24","react":"^18.3.1","react-dom":"^18.3.1","rimraf":"^6.0.1","tsup":"^8.3.5","typescript":"^5.9.3"},"publishConfig":{"access":"public"},"gitHead":"2fb8e01f6ea7d41bf480d058a8c99b32dd2e53cb","_id":"@academix-admin/search-viewer@0.3.0","_nodeVersion":"24.15.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-3sx21DStH6s+V4UqE7W1gL8wE6nWUl+jPlgjKKakMXGwKi61pZhDR0QZmqJ1CYsSuLnU581/WkA9c8dWGUO8dw==","shasum":"96ec192d7f7e731b05bdbf3b6e57440afc8f31ee","tarball":"https://registry.npmjs.org/@academix-admin/search-viewer/-/search-viewer-0.3.0.tgz","fileCount":9,"unpackedSize":295643,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICAB1o7wt9ERDQQYdhMgWVh52dKDwYmz2WMJzioTboitAiAWAp3pKak402t6sXwWQuqJV+5T6JnKYO2i8elZeRHwjA=="}]},"_npmUser":{"name":"academix-group","email":"academix.tech4u@gmail.com"},"directories":{},"maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/search-viewer_0.3.0_1787525093836_0.34723798693184893"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-21T18:04:39.553Z","modified":"2026-08-23T22:44:54.359Z","0.1.0":"2026-07-21T18:04:39.863Z","0.1.1":"2026-08-01T16:34:45.055Z","0.1.2":"2026-08-03T10:55:02.459Z","0.1.3":"2026-08-05T05:14:07.619Z","0.1.4":"2026-08-05T09:30:14.394Z","0.2.0":"2026-08-07T23:05:13.158Z","0.2.1":"2026-08-23T22:41:30.291Z","0.3.0":"2026-08-23T22:44:54.002Z"},"bugs":{"url":"https://github.com/academix-admin/academix-ui/issues"},"author":{"name":"Academix"},"license":"MIT","homepage":"https://github.com/academix-admin/academix-ui/tree/main/packages/search-viewer#readme","keywords":["react","search","autocomplete","combobox","multi-select","picker","debounce"],"repository":{"type":"git","url":"git+https://github.com/academix-admin/academix-ui.git","directory":"packages/search-viewer"},"description":"Headless-friendly search & selection UI for React â€” debounced controller, single/multi select, and sheet-based pickers.","maintainers":[{"name":"academix-group","email":"academix.tech4u@gmail.com"}],"readme":"# @academix-admin/search-viewer\n\nA batteries-included **search & selection UI** for React — a debounced search\ncontroller plus a sheet-based results viewer that handles local filtering *and*\nasync, cursor-paginated queries, with loading / empty / error states built in.\n\n- 🔎 Debounced search with request cancellation (`AbortSignal`)\n- 🌐 Local (`onInitialData`) **or** remote (`queryData`) data sources\n- 📄 Cursor pagination, de-duplication, online/offline result tagging\n- 🧾 First-class loading / no-result / error views\n- 🧰 `useSearchController()` to open/close and track state from anywhere\n- 📱 Presented in a gesture-driven sheet (via `@academix-admin/modal-sheet`)\n- Single & multi-select (`SearchViewer`, `MultipleSearchViewer`, `EachViewer`)\n\n## Install\n\n```bash\nnpm install @academix-admin/search-viewer\n# peer deps (modal-sheet is a direct dependency and installs automatically)\nnpm install react react-dom motion\n```\n\n> Depends on `@academix-admin/modal-sheet` (installed for you) and shares your app's\n> `motion` peer.\n\n## Usage\n\nDrive it with the controller hook, then render the viewer:\n\n```tsx\n'use client';\nimport { SearchViewer, useSearchController, type SearchResult } from '@academix-admin/search-viewer';\n\ntype Friend = { id: string; name: string };\ntype Cursor = { page: number };\n\nexport default function FriendSearch() {\n  const [searchId, search, isOpen, searchState] = useSearchController();\n\n  return (\n    <>\n      <button onClick={search.open}>Search friends</button>\n\n      <SearchViewer<Friend, Cursor>\n        isOpen={isOpen}\n        onClose={search.close}\n        searchState={searchState}\n        debounceMs={300}\n        searchProp={{ text: 'Search friends', textColor: '#111' }}\n        // Remote, cursor-paginated source with cancellation:\n        queryData={async (cursor, text, signal) => {\n          const res = await fetch(\n            `/api/friends?q=${text}&page=${cursor?.page ?? 0}`,\n            { signal },\n          );\n          const json = await res.json();\n          return { data: json.items, nextCursor: json.next, hasMore: json.hasMore };\n        }}\n        onRemoveDuplicateBy={(f) => f.id}\n      >\n        {({ results }: { results: SearchResult<Friend>[] }) =>\n          results.map((r) => <div key={r.data.id}>{r.data.name}</div>)\n        }\n      </SearchViewer>\n    </>\n  );\n}\n```\n\nFor a purely local list, provide `onInitialData` instead of `queryData`:\n\n```tsx\n<SearchViewer<Friend>\n  isOpen={isOpen}\n  onClose={search.close}\n  onInitialData={(text) =>\n    allFriends.filter((f) => f.name.toLowerCase().includes(text.toLowerCase()))\n  }\n  localDataDeps={[allFriends]}\n>\n  {/* render results */}\n</SearchViewer>\n```\n\n## Composable sections: `Row` / `Column`\n\nFor sectioned results (e.g. one horizontally-scrolling shelf per topic/category), compose\n`Row`s inside a `Column` as `SearchViewer`'s `children`. Today's flat `children` usage is,\nunchanged, an implicit `Column` with no `Row`s — `Column`'s default layout is identical to\nthat existing vertical flow.\n\n```tsx\n<SearchViewer isOpen={isOpen} onClose={search.close} searchProp={{ text: 'Search', textColor: '#111' }}>\n  <Column>\n    <h3>Trending</h3>\n    <Row queryData={fetchTrending} onRemoveDuplicateBy={(f) => f.id}>\n      {({ results }) => results.map((r) => <FriendCard key={r.data.id} friend={r.data} />)}\n    </Row>\n\n    <h3>Nearby</h3>\n    <Row queryData={fetchNearby} onRemoveDuplicateBy={(f) => f.id}>\n      {({ results }) => results.map((r) => <FriendCard key={r.data.id} friend={r.data} />)}\n    </Row>\n  </Column>\n</SearchViewer>\n```\n\nEach `Row` is independently paginating (triggers `queryData` for its next page as it's\nscrolled horizontally near its end) and reads the live search text automatically — no\n`containerRef` or manual wiring needed. `Column` collects every `Row`'s state and reports\none cumulative state up to `SearchViewer`, so `loadingProp` / `noResultProp` / `errorProp`\nreact automatically: no result from ANY row → the outer no-result view; any row still\nloading (and none have data yet) → the outer loading view; and so on. `Column`s can also\nnest inside each other — an inner `Column` reports up exactly like a `Row` would.\n\n## `useSearchController(initialState?)`\n\nReturns a tuple `[searchId, operations, isOpen, searchState]`:\n\n| Element | Type | Description |\n|---------|------|-------------|\n| `searchId` | `string` | Stable unique id for this search instance. |\n| `operations` | `{ open, close, toggle, setSearchState }` | Imperative controls. |\n| `isOpen` | `boolean` | Whether the viewer is open. |\n| `searchState` | `SearchState` | Current lifecycle state. |\n\n## Key `SearchViewer` props\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `isOpen` / `onClose` | `boolean` / `() => void` | **Required.** Open state + close handler. |\n| `queryData` | `(cursor, text, signal?) => Promise<QueryResult<T, C>>` | Async, cursor-paginated source. |\n| `onInitialData` | `(text: string) => T[]` | Synchronous local source. |\n| `localDataDeps` | `DependencyList` | Recompute local data when these change. |\n| `debounceMs` | `number` | Debounce for input → query. |\n| `onRemoveDuplicateBy` | `(item: T) => any` | Key selector for de-duplication. |\n| `onResult` | `(results: SearchResult<T>[]) => void` | Observe result changes. |\n| `searchProp` | `SearchProps` | Search bar text, icons, colors, styling. |\n| `loadingProp` / `noResultProp` / `errorProp` | — | Custom state views. |\n| `layoutProp` | `LayoutProps` | Sheet/header layout + theming. |\n| `childrenDirection` | `'vertical' \\| 'horizontal'` | Result flow direction. |\n| `unmountOnClose` | `boolean` | Unmount contents when closed. |\n| `zIndex` / `maxHeight` / `minHeight` | — | Presentation sizing. |\n\n`MultipleSearchViewer` and `EachViewer` build on the same engine for multi-select\nand composed layouts. Types (`SearchResult`, `SearchViewerProps`, …) are exported.\n\n## License\n\nMIT © Academix\n","readmeFilename":"README.md"}