(feat) auto-Kana with wanakana 🐊

This commit is contained in:
polv committed 2026-02-28 15:11:53 +07:00
1 parent 641f23538b
commit e3ccd517a8
3 files changed
+67 -12

No files matched your search

+9
View File
@@ -44,6 +44,9 @@ importers:
react-icons:
specifier: ^5.5.0
version: 5.5.0(react@19.2.4)
wanakana:
specifier: ^5.3.1
version: 5.3.1
zustand:
specifier: ^5.0.11
version: 5.0.11(@types/react@19.2.14)(react@19.2.4)
@@ -1195,6 +1198,10 @@ packages:
yaml:
optional: true
wanakana@5.3.1:
resolution: {integrity: sha512-OSDqupzTlzl2LGyqTdhcXcl6ezMiFhcUwLBP8YKaBIbMYW1wAwDvupw2T9G9oVaKT9RmaSpyTXjxddFPUcFFIw==}
engines: {node: '>=12'}
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
@@ -2618,6 +2625,8 @@ snapshots:
'@types/node': 24.10.13
fsevents: 2.3.3
wanakana@5.3.1: {}
yallist@3.1.1: {}
yaml@1.10.2: {}
+1
View File
@@ -19,6 +19,7 @@
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"wanakana": "^5.3.1",
"zustand": "^5.0.11"
},
"devDependencies": {
+57 -12
View File
@@ -1,6 +1,16 @@
import { CompositionEventHandler, useEffect, useRef, useState } from "react";
import { toHiragana } from "wanakana";
import { Box, Button, Card, Group, Input, Stack } from "@chakra-ui/react";
import {
Box,
Card,
CloseButton,
Group,
Input,
InputGroup,
Stack,
Switch,
} from "@chakra-ui/react";
import { invoke } from "@tauri-apps/api/core";
import Glossary from "../components/Glossary";
@@ -22,7 +32,10 @@ function SearchPage() {
const [entries, setEntries] = useState<Entry[]>([]);
const [searchTimeout, setSearchTimeout] = useState(0);
const [furigana, setFurigana] = useState("");
const [isAutoKana, set_isAutoKana] = useState(true);
const nSearch = useRef(0);
const searchboxRef = useRef<HTMLInputElement | null>(null);
const lang = "ja-JP";
@@ -89,6 +102,14 @@ function SearchPage() {
);
}
function onSearchboxChange(q: string) {
if (isAutoKana) {
q = toHiragana(q, { useObsoleteKana: true, IMEMode: true });
}
setQ(q);
}
const FURIGANA_REGEX = /^[\p{scx=Hiragana}\p{scx=Katakana}]+$/u;
const KANJI_REGEX = /([\p{sc=Han}\p{N}々〆ヵヶ]+)/u;
@@ -134,6 +155,17 @@ function SearchPage() {
: k;
}
const clearButton = q.trim() ? (
<CloseButton
size={"xs"}
me={-2}
onClick={() => {
setQ("");
searchboxRef.current ? searchboxRef.current.focus() : null;
}}
/>
) : null;
return (
<Stack maxW={"1000px"} margin={"0.5em auto"}>
<form
@@ -143,18 +175,31 @@ function SearchPage() {
}}
>
<Group attached w="full">
<Input
id="greet-input"
value={q}
onChange={(e) => setQ(e.currentTarget.value)}
onCompositionUpdate={updateFurigana}
onCompositionEnd={addFurigana}
autoComplete="off"
spellCheck={false}
placeholder="Search..."
/>
<Button type="submit">Search</Button>
<InputGroup endElement={clearButton}>
<Input
id="greet-input"
ref={searchboxRef}
value={q}
onChange={(e) => onSearchboxChange(e.currentTarget.value)}
onCompositionUpdate={updateFurigana}
onCompositionEnd={addFurigana}
autoComplete="off"
spellCheck={false}
placeholder="Search..."
/>
</InputGroup>
{/* <Button type="submit">Search</Button> */}
</Group>
<div style={{ marginTop: "0.5em" }}>
<Switch.Root
checked={isAutoKana}
onCheckedChange={(d) => set_isAutoKana(d.checked)}
>
<Switch.HiddenInput />
<Switch.Control />
<Switch.Label>Auto-convert Kana</Switch.Label>
</Switch.Root>
</div>
</form>
<Box as={"ol"} listStyleType={"number"} style={{ margin: "1em" }}>
{entries.map(