0xf

日記だよ

inkでReact / CLI

ink は ClaudeCode のCUIを組み立てているReactベースの何かです。何か、というのは、なんだろう...? と思ってしまうからですね。これはなんなんだろう。フレームワーク?

github.com

以下の簡単な計算機(足し算しかできない)は、ほぼ 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の使い方あんまりまだ馴染んでないんですよね。動きはわかる。ベストプラクティスやアンチパターンっぽいやつがまだわからん。とはいえだいぶ議論も出揃ってる感じはするから粛々と追っていこう。