TypeScript で作成した UI のサンプル

Hugo で TypeScript を利用して作成した UI のサンプルです。

アプリ

UI Sample

Text:

Checked: False

Selected: option1

Selected: option1


スクリプト

import * as React from 'react';
import { createRoot } from 'react-dom/client';
import styled from 'styled-components';

// スタイルコンポーネントを定義
const Container = styled.div`
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  width: 400px;
  font-family: Arial, sans-serif;
`;

const Title = styled.h1`
  text-align: center;
  margin-bottom: 20px;
`;

const Button = styled.button`
  display: block;
  width: 100%;
  padding: 10px;
  margin-bottom: 20px;
  background-color: #5e85ce;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
`;

const InputGroup = styled.div`
  margin-bottom: 20px;
`;

const Label = styled.label`
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
`;

const TextInput = styled.input`
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
`;

const Checkbox = styled.input.attrs({ type: 'checkbox' })`
  accent-color: #5e85ce;
  width: 20px;
  height: 20px;
`;

const Radio = styled.input.attrs({ type: 'radio' })`
  accent-color: #5e85ce;
  width: 20px;
  height: 20px;
`;

const Select = styled.select`
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
`;

const Pixel = styled.div<{ color: string }>`
  width: 20px;
  height: 20px;
  background-color: ${({ color }) => color};
  cursor: pointer;
`;

const GRID_SIZE = 16;

function App() {
	const [text, setText] = React.useState('');
	const [checked, setChecked] = React.useState(false);
	const [selectedOption, setSelectedOption] = React.useState('option1');
	const [pixels, setPixels] = React.useState<string[][]>(
		Array(GRID_SIZE).fill(Array(GRID_SIZE).fill('#ffffff'))
	);

	const handlePixelClick = (x: number, y: number) => {
		const newPixels = pixels.map((row, rowIndex) =>
			row.map((color, colIndex) => {
				if (rowIndex === y && colIndex === x) {
					return color === '#000000' ? '#ffffff' : '#000000';
				}
				return color;
			})
		);
		setPixels(newPixels);
	};

	return (
		<React.StrictMode>
			<Container>
				<Title>UI Sample</Title>

				{/* Button */}
				<Button onClick={() => alert('Button clicked.')}>Click</Button>

				{/* Text input */}
				<InputGroup>
					<Label htmlFor="TextInput">Text Input</Label>
					<TextInput
						id="textInput"
						type="text"
						value={text}
						onChange={(e) => setText(e.target.value)}
						placeholder="Text Input"
					/>
					<p>Text: {text}</p>
				</InputGroup>

				{/* チェックボックス */}
				<InputGroup>
					<Label>
						<Checkbox
							checked={checked}
							onChange={(e) => setChecked(e.target.checked)}
						/>
						Check box
					</Label>
					<p>Checked: {checked ? 'True' : 'False'}</p>
				</InputGroup>

				{/* ラジオボタン */}
				<InputGroup>
					<Label>
						<Radio
							name="radioGroup"
							value="Option1"
							checked={selectedOption === 'option1'}
							onChange={(e) => setSelectedOption(e.target.value)}
						/>
						Option1
					</Label>
					<Label>
						<Radio
							name="radioGroup"
							value="Option2"
							checked={selectedOption === 'Option2'}
							onChange={(e) => setSelectedOption(e.target.value)}
						/>
						Option2
					</Label>
					<p>Selected: {selectedOption}</p>
				</InputGroup>

				{/* ドロップダウンメニュー */}
				<InputGroup>
					<Label htmlFor="dropdown">Drop down menu</Label>
					<Select
						id="dropdown"
						value={selectedOption}
						onChange={(e) => setSelectedOption(e.target.value)}
					>
						<option value="option1">Option1</option>
						<option value="option2">Option2</option>
						<option value="option3">Option3</option>
					</Select>
					<p>Selected: {selectedOption}</p>
				</InputGroup>
			</Container>
		</React.StrictMode>
	);
}

export function render(node: HTMLElement) {
	createRoot(node).render(<App />);
}