UNPKG

korean-search-utils

Version:

한글 초성 검색 및 React 훅 지원 라이브러리

130 lines (95 loc) 3.81 kB
# korean-search-utils React 기반 프로젝트에서 **한글 검색**을 지원하는 유틸리티 함수와 커스텀 훅입니다. ## ✨ 주요 기능 - 한글 자모 분리 (`disassembleHangul`) - 초성/중성/종성 fuzzy 검색 (`isMatch`) - 매칭 구간 하이라이팅 세그먼트 반환 (`getMatchSegments`) — v1.1.0 - React 없이 쓸 수 있는 필터+정렬 유틸 (`filterAndSort`) — v1.1.0 - React 커스텀 훅 (`useKoreanSearch`) - ESM + CJS 듀얼 빌드 지원 — v1.1.0 ## 📦 설치 ```bash npm install korean-search-utils ``` ## 📘 사용법 ### useKoreanSearch 훅 ```tsx import { useKoreanSearch } from "korean-search-utils"; const fruits = [ { name: "사과 apple" }, { name: "오렌지 orange" }, { name: "바나나 banana" }, ]; function FruitSearch() { const { searchTerm, setSearchTerm, filteredItems, resetSearch } = useKoreanSearch(fruits, (fruit) => fruit.name); return ( <div> <input placeholder="과일 검색 (ㅅㄱ, 바나, apple...)" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> <button onClick={resetSearch}>초기화</button> <ul> {filteredItems.map((fruit) => ( <li key={fruit.name}>{fruit.name}</li> ))} </ul> </div> ); } ``` ### getMatchSegments — 하이라이팅 ```tsx import { getMatchSegments } from "korean-search-utils"; const segments = getMatchSegments("사과 apple", "ㅅ"); // → [{ text: "사", matched: true }, { text: "과 apple", matched: false }] // 하이라이팅 렌더링 예시 segments.map((seg) => seg.matched ? <mark>{seg.text}</mark> : <span>{seg.text}</span> ); ``` ### filterAndSort — React 없이 사용 ```ts import { filterAndSort } from "korean-search-utils"; const fruits = ["사과", "바나나", "오렌지", "딸기", "수박"]; filterAndSort(fruits, "ㅅ", (x) => x); // → ["사과", "수박"] (ㅅ으로 시작하는 항목, 매칭 위치 순 정렬) filterAndSort(fruits, "바나", (x) => x); // → ["바나나"] ``` ### 유틸 함수 ```ts import { disassembleHangul, isMatch, getMatchStartIndex, getMatchScore } from "korean-search-utils"; disassembleHangul("사과"); // "ㅅㅏㄱㅘ" disassembleHangul("한글 hangul"); // "ㅎㅏㄴㄱㅡㄹhangul" isMatch("사과", "ㅅㄱ"); // true isMatch("바나나", "ㅂㄴ"); // true isMatch("딸기", "포도"); // false getMatchStartIndex("사과", "ㅅ"); // 0 (자모 기준 인덱스) getMatchStartIndex("사과", "없음"); // -1 getMatchScore("사과", "ㅅ"); // 숫자 (낮을수록 상위) getMatchScore("사과", "포도"); // Infinity (매칭 없음) ``` ### 매칭 우선순위 - 검색어가 더 **앞에서** 매칭되는 항목을 우선 정렬합니다. - 같은 시작 위치라면 **짧은 문자열**이 우선됩니다. ```ts const list = [{ name: "사과 오렌지" }, { name: "오렌지 사과" }]; filterAndSort(list, "ㅅㄱ", (x) => x.name); // 1) "사과 오렌지" (매칭 시작 인덱스 0) // 2) "오렌지 사과" (매칭 시작 인덱스 더 뒤) ``` ## 📖 API | 함수 | 설명 | |------|------| | `disassembleHangul(str)` | 문자열을 자모로 분리 (공백 제거) | | `isMatch(source, target)` | source가 target을 포함하는지 여부 | | `getMatchStartIndex(source, target)` | 매칭 시작 자모 인덱스 (-1이면 불일치) | | `getMatchScore(source, target)` | 매칭 품질 점수 (낮을수록 상위, 불일치 시 Infinity) | | `getMatchSegments(source, target)` | 하이라이팅용 세그먼트 배열 반환 | | `filterAndSort(items, target, getField)` | 필터+정렬 (React 불필요) | | `useKoreanSearch(items, getField)` | React 커스텀 훅 | ## 📄 라이선스 MIT