0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】ChakraUIでお問い合わせフォームを作る

Posted at

ChakraUIを使ってお問い合わせフォームを作ってみます。

完成イメージ

image.png

ボタンにカーソルを合わせると
image.png

image.png

ChakraUIのバージョン

今回は、chakra-ui/reactの最新バージョン3.29.0を使用しています。

ChakraUI(v3系)を使うにあたって

@chakra-ui/react@3.xではChakraProviderは テーマオブジェクトを value prop に渡す必要がある ように変更されています。
そのため、以下のように書かないと型エラーが出ます。

main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ChakraProvider, defaultSystem } from '@chakra-ui/react'; // ✅ v3はdefaultSystemが必要
import App from './App';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ChakraProvider value={defaultSystem}>{/* ✅ ← v3では必須 */}
      <App />
    </ChakraProvider>
  </React.StrictMode>
);

💡 補足

1.defaultSystemChakra UI v3で導入された テーマシステムオブジェクト です。
2.value prop に渡すことで、内部でテーマやデザイントークンが解決されます。
3.v2以前ではtheme propextendTheme()の結果を渡していましたが、v3ではこれが value に変わりました。

コード

完成形のコードです。

fieldSet.tsx
import {
  Button,
  Field,
  Fieldset,
  For,
  Input,
  NativeSelect,
  Stack,
  Group,
  Textarea,
  Flex,
} from '@chakra-ui/react';
import { Tooltip } from '@/components/ui/tooltip'; //ツールチップのコンポーネント

const FieldsetComponent = () => {
  return (
    <Flex
      justify="center" // 水平方向中央
      align="center" // 垂直方向中央
      minH="100vh" // ビューポート全体の高さ確保
      backgroundColor="gray.100" // 背景色(任意)
    >
      <Fieldset.Root size="lg" maxW="md">
        <Stack>
          <Fieldset.Legend>お問い合わせフォーム</Fieldset.Legend>
          <Fieldset.HelperText>以下の項目をご入力ください。</Fieldset.HelperText>
        </Stack>

        <Fieldset.Content>
          <Field.Root>
            <Field.Label>お名前(Name)</Field.Label>
            <Input
              name="name"
              borderColor="black"
              _hover={{ borderColor: 'black' }}
              focusRingColor="black"
            />
          </Field.Root>

          <Field.Root>
            <Field.Label>メールアドレス(Email address)</Field.Label>
            <Input
              name="email"
              type="email"
              borderColor="black"
              _hover={{ borderColor: 'black' }}
              focusRingColor="black"
            />
          </Field.Root>

          <Field.Root>
            <Field.Label>国名</Field.Label>
            <NativeSelect.Root>
              <NativeSelect.Field
                name="country"
                borderColor="black"
                _hover={{ borderColor: 'black' }}
                focusRingColor="black"
              >
                <For each={['日本', '米国', 'その他']}>
                  {(item) => (
                    <option key={item} value={item}>
                      {item}
                    </option>
                  )}
                </For>
              </NativeSelect.Field>
              <NativeSelect.Indicator />
            </NativeSelect.Root>
          </Field.Root>
          <Field.Root>
            <Field.Label>お問い合わせ内容</Field.Label>
            <Textarea
              placeholder="お問い合わせ内容をお書きください。"
              borderColor="black"
              _hover={{ borderColor: 'black' }}
              focusRingColor="black"
            />
          </Field.Root>
        </Fieldset.Content>

        {/*Groupコンポーネントでボタンを横並び尾設定*/}
        <Group>
          {/*ツールチップ設定*/}
          <Tooltip content="登録確認画面に移動します。">
            <Button
              type="submit"
              backgroundColor="blue.500"
              _hover={{ backgroundColor: 'blue.700' }}
              alignSelf="flex-start"
            >
              登録
            </Button>
          </Tooltip>

          {/*ツールチップ設定*/}
          <Tooltip
            showArrow
            content="前の画面に戻ります"
            contentProps={{ css: { '--tooltip-bg': 'tomato' } }}
          >
            <Button type="button" alignSelf="flex-start">
              戻る
            </Button>
          </Tooltip>
        </Group>
      </Fieldset.Root>
    </Flex>
  );
};

export default FieldsetComponent;

🌟ポイント

上下中央寄せはFlexコンポーネントを使って作成

Flexコンポーネントを使って親コンテナを中央寄せにしました。

fieldSet.tsx
import {
  Button,
  Field,
  Fieldset,
  For,
  Input,
  NativeSelect,
  Stack,
  Group,
  Textarea,
  Flex,             // ✅ 追加
} from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
const FieldsetComponent = () => {
  return (
    // ✅ Flexで中央寄せ
    <Flex
      justify="center"   // 水平方向中央
      align="center"     // 垂直方向中央
      minH="100vh"       // ビューポート全体の高さ確保
      bg="gray.50"       // 背景色(任意)
    >
    
    //(中略)
    
    </Flex>
  )
}
export default FieldsetComponent
ポイント解説
 プロパティ   意味 
 minH="100vh"   画面の高さ全体を確保(100% viewport height) 
 justify="center"   横方向の中央寄せ 
 align="center"   縦方向の中央寄せ 
 maxW="md", w="100%"   コンテンツの幅を固定しつつ、モバイル対応 
 boxShadow="md"・borderRadius="md"   見栄えを少し整える(任意) 

上下中央ぞろえする別の方法

App 側で中央寄せしたい場合

App.tsx でこのフォームコンポーネントを中央寄せしたいなら、
以下のようにラップできます。

App.tsx
import { Flex } from "@chakra-ui/react"
import FieldsetComponent from "./chakraComponents/ui/fieldSet"

function App() {
  return (
    <Flex justify="center" align="center" minH="100vh" bg="gray.50">
      <FieldsetComponent />
    </Flex>
  )
}

ToolTipを導入

ToolTipを使うには下記をImportします。
<ToolTip>タグでオブジェクトを挟み込み、contentに吹き出しする内容を記載します。

fieldSet.tsx
//(前略)
import { Tooltip } from '@/components/ui/tooltip'; //ツールチップのコンポーネント

const FieldsetComponent = () => {
  return (
        //(中略)
          {/*ツールチップ設定*/}
          <Tooltip content="登録確認画面に移動します。">
            <Button
              type="submit"
              backgroundColor="blue.500"
              _hover={{ backgroundColor: 'blue.700' }}
              alignSelf="flex-start"
            >
              登録
            </Button>
          </Tooltip>

          {/*ツールチップ設定*/}
          <Tooltip
            showArrow
            content="前の画面に戻ります"
            contentProps={{ css: { '--tooltip-bg': 'tomato' } }}
          >
            <Button type="button" alignSelf="flex-start">
              戻る
            </Button>
          </Tooltip>
        //(中略)
  );
};

export default FieldsetComponent;

ボタンをグループ化

ボタンのグループ化はGroupタグを使用します。

fieldSet.tsx
import {
 //(前略)
  Group,
 //(後略)
} from '@chakra-ui/react';
//(後略)

const FieldsetComponent = () => {
  return (
        //(中略)
        {/*Groupコンポーネントでボタンを横並び尾設定*/}
        <Group>
          {/*ツールチップ設定*/}
          <Tooltip content="登録確認画面に移動します。">
            <Button
              type="submit"
              backgroundColor="blue.500"
              _hover={{ backgroundColor: 'blue.700' }}
              alignSelf="flex-start"
            >
              登録
            </Button>
          </Tooltip>

          {/*ツールチップ設定*/}
          <Tooltip
            showArrow
            content="前の画面に戻ります"
            contentProps={{ css: { '--tooltip-bg': 'tomato' } }}
          >
            <Button type="button" alignSelf="flex-start">
              戻る
            </Button>
          </Tooltip>
        </Group>
        //(後略)
  );
};

export default FieldsetComponent;

サイト

ChakraUI関連

FieldSet

Text

Group

Conditional Styles

Textarea

Tooltip

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?