1
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?

この記事の概要

Ark UIのSelectコンポーネントには単体のSelectFiledに属すSelectが存在します。

これらの違いと使い分けを備忘録がてら記事にしました。

Ark UIは色々なフレームワークで使えますが、この記事での例示コードはReactです。

結論

通常のselect要素の見た目、使い勝手で十分な際はField.Selectを。
見た目や出現時のアニメーション、選択していることの示し方などにこだわりたいときはSelectを選ぶと良いと思います。

メリット デメリット
Field.Select コードがシンプルで見やすい・分かりやすい 通常のselect要素とoption要素でできること以上のことは無い
Select 表示の仕方やアニメーションなど細かい箇所にこだわれる 単なるselectとして使うには複雑な箇所が多い

両者の違い

説明のしやすさの都合上、Field.Selectから説明します。

Field.Select

exampleのコードは以下のようになっています。

import { Field } from '@ark-ui/react/field'

export const Select = () => {
  return (
    <Field.Root>
      <Field.Label>Label</Field.Label>
      <Field.Select>
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
      </Field.Select>
      <Field.HelperText>Some additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}
  • Filed.Root
    • Filed関連のpropsを伝播させるためのprovider
  • Field.Label
    • idやdata属性などが良い感じに付与されたlabel要素
  • Filed.Select
    • iddata属性などが良い感じに付与されたselect要素
  • Filed.HelperText, Field.ErrorText
    • 今回の話にはほぼ関係ないので省略
    • ErrorTextに関しての記事を別で書いているので良ければこちらもご覧ください

つまり、最終的なマークアップとしてはdivの中にlabelselectと少々のテキスト系要素が入っているだけです。

何もせずともlabelselectを紐づけてくれるなど気が利いてはいますが、実態としては単なるselect要素でしかない、と言えます。

Select

exampleのコードは以下のようになっています。

import { Portal } from '@ark-ui/react/portal'
import { Select, createListCollection } from '@ark-ui/react/select'
import { ChevronDownIcon } from 'lucide-react'

export const Basic = () => {
  const collection = createListCollection({ items: ['React', 'Solid', 'Vue'] })

  return (
    <Select.Root collection={collection}>
      <Select.Label>Framework</Select.Label>
      <Select.Control>
        <Select.Trigger>
          <Select.ValueText placeholder="Select a Framework" />
          <Select.Indicator>
            <ChevronDownIcon />
          </Select.Indicator>
        </Select.Trigger>
        <Select.ClearTrigger>Clear</Select.ClearTrigger>
      </Select.Control>
      <Portal>
        <Select.Positioner>
          <Select.Content>
            <Select.ItemGroup>
              <Select.ItemGroupLabel>Frameworks</Select.ItemGroupLabel>
              {collection.items.map((item) => (
                <Select.Item key={item} item={item}>
                  <Select.ItemText>{item}</Select.ItemText>
                  <Select.ItemIndicator></Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Portal>
      <Select.HiddenSelect />
    </Select.Root>
  )
}

Field.Selectとはコードの長さがだいぶ違います。
すべてを説明するとかなり長くなってしまうので、かいつまんで記載します。

  • Select.Root
    • Select関連のpropsを伝播させるためのprovider
  • Select.Controlとその配下
    • ざっくり言えば、これらの要素がクリックされると選択肢一覧が表示される
    • Select.ValueTextSelect.Indicatorはあくまで「よくある要素」として使われているに過ぎないというか、どれかを無くしても問題なく動作する
  • PortalSelect.Positioner
    • Ark UIのSelectは通常のselect要素とは違い、ポップオーバー的にoption群が表示される
    • そのため、それらの位置を制御するようなもの
  • Select.Contentとその配下
    • 通常のselectでいうoption要素達

またreturnの前にcreateListCollectionという関数を使ってcollectionを定義しています。

単なる配列やオブジェクトを渡してもダメで、こちらの関数を通してからSelectに渡す必要があります。
これのおかげで複数選択ができたり前後のオプションの情報を得たり、色々なことができるようになっている、ように見えます1

Selectのおまけ

Select.Positionerのスタイルには、親要素の幅・画面上で表示できる幅と高さが計算され、以下のCSSカスタムプロパティに渡ります。

--reference-width:
--available-width:
--available-height:

これらを用いると、狙ったスタイリングもしやすいかと思います。

参考

  1. すみません。型を見る限りそのように見えるものの、ちゃんと検証できてはいません。

1
0
1

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
1
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?