ink は ClaudeCode のCUIを組み立てているReactベースの何かです。何か、というのは、なんだろう...? と思ってしまうからですね。これはなんなんだろう。フレームワーク?
以下の簡単な計算機(足し算しかできない)は、ほぼ Cursorの一発出しなんだけど、だいたい雰囲気わかった。テキストボックス間は Tab キーで移動できるし、値の変更はちゃんと計算結果に反映される。ESCキーの入力なども適切に拾っている。すごい。
#!/usr/bin/env npx tsx import React, { useState } from 'react'; import { render, Box, Text, useApp, useInput } from 'ink'; import TextInput from 'ink-text-input'; const Help = () => ( <Box flexDirection="column" justifyContent="center" alignItems="center" height={10}> <Text>"welcome help"</Text> </Box> ); const CalcApp = () => { const { exit } = useApp(); const [showHelp, setShowHelp] = useState(false); const [value1, setValue1] = useState('0'); const [value2, setValue2] = useState('0'); const [focusIndex, setFocusIndex] = useState(0); // 0: value1, 1: value2 useInput((input, key) => { if (key.ctrl && input === 'c') { exit(); } if (key.escape) { setShowHelp((prev) => !prev); } if (!showHelp) { if (key.tab) { setFocusIndex((prev) => (prev === 0 ? 1 : 0)); } } }); if (showHelp) { return <Help />; } const num1 = Number(value1); const num2 = Number(value2); const sum = (!isNaN(num1) && !isNaN(num2)) ? num1 + num2 : ''; return ( <Box flexDirection="column" height={10}> {/* タイトル */} <Box justifyContent="center" marginBottom={1}> <Text color="cyan">Calc</Text> </Box> {/* 入力欄 */} <Box flexDirection="column" alignItems="center" flexGrow={1} justifyContent="center"> <Box> <Text>値1: </Text> <TextInput value={value1} onChange={setValue1} focus={focusIndex === 0} /> </Box> <Box> <Text>値2: </Text> <TextInput value={value2} onChange={setValue2} focus={focusIndex === 1} /> </Box> </Box> {/* 合計 */} <Box justifyContent="center" marginTop={1}> <Text>合計: {sum}</Text> </Box> </Box> ); }; render(<CalcApp />);
レイアウトシステムは Yoga。全てをフレックスボックスでデザインせよって感じぽい。
この記事みたいに、ちょっと立て込んだ画面を作ってみないとわかんない感じはする。
hooksの使い方あんまりまだ馴染んでないんですよね。動きはわかる。ベストプラクティスやアンチパターンっぽいやつがまだわからん。とはいえだいぶ議論も出揃ってる感じはするから粛々と追っていこう。