reka-ui-skilld について
Reka UIは、カスタムインターフェースを構築するVue 3開発者向けの、スタイルを持たないアクセシブルなコンポーネントプリミティブです。組み合わせ可能なパーツで一般的なUIパターンを構成でき、合成、設定、仮想化のユーティリティも備えています。
主な機能
- 01スタイルなしのアクセシブルなVueコンポーネントプリミティブ
- 02ダイアログ、メニュー、日付、カラーコンポーネント
- 03組み合わせ可能なコンポーネントパーツとユーティリティ
- 04RTL、ロケール、テレポート先の設定
- 05長いリスト向けの仮想化機能
活用シーン
- 01独自スタイルのアクセシブルなUIを構築
- 02ダイアログ、メニュー、ピッカーを構成
- 03ロケールと右から左へのレイアウトを設定
- 04長いコンポーネントリストを仮想化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ skilld-dev/ vue-ecosystem-skills --skill reka-ui-skilldインストール後、Claude Code で/reka-ui-skilldを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api-surface.mdcomponents-new.mdcomposition.mdintegrations.mdstyling-animation.md詳細
Reka UI [email protected]
Vue 3 向けのスタイルを持たない、アクセシブルなコンポーネントプリミティブです。vue >= 3.4.0
が必要です(用意されたソース package.json:87-89)。ドキュメント:https://reka-ui.com
参考資料
- API の概要:エントリーポイント、各コンポーネントのパーツ、ユーティリティ。
- コンポジション:
asChild、プロパティの転送、コンテキストの注入、制御された状態。 - スタイリングとアニメーション:
data-state、--reka-CSS 変数、<Transition>によるforce-mount。 - 新規・変更コンポーネント:Drawer、Autocomplete、Color プリミティブ、Month/Year ピッカー、バージョン固有のプロパティの変更。
- インテグレーション:名前空間付きエントリー、Nuxt モジュール、コンポーネントリゾルバー、
@internationalized/dateによる日付、仮想化。
セットアップ
pnpm add reka-ui # or npm / yarn / bun
<script setup lang="ts">
import { DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogTitle } from 'reka-ui'
</script>
<template>
<DialogRoot>
<DialogTrigger>Edit profile</DialogTrigger>
<DialogPortal>
<DialogOverlay />
<DialogContent>
<DialogTitle>Edit profile</DialogTitle>
</DialogContent>
</DialogPortal>
</DialogRoot>
</template>
API の変更(2.10.x および 2.9.x)
最近のリリースを優先して記載しています。ベースラインのスキルは 2.9.7 までを対象としていました。
- 新規
Drawerプリミティブ(2.10.0):スワイプで閉じる、スナップポイント、ネストされたドロワーに対応します。パーツ:DrawerRoot/Trigger/Portal/Overlay/Content/Close/Title/Description/Handle/SwipeArea/Viewport/Indent/IndentBackground(準備済みソースsrc/Drawer/)。リリース:https://github.com/unovue/reka-ui/releases/tag/v2.10.0 - 新規
ConfigProviderのteleportToプロパティ:テレポート先のグローバルなデフォルト値(準備済みソースsrc/ConfigProvider/ConfigProvider.vue:45) - 新規
DialogRootのunmountOnHideプロパティ。デフォルトはtrueです。非表示時もコンテンツをマウントしたままにするにはfalseを設定します(準備済みソースsrc/Dialog/DialogRoot.vue:20) - 新規
SelectRootのnullableValueプロパティ:空の選択状態を表す隠し入力の値を指定します(準備済みソースsrc/Select/SelectRoot.vue:18) - 新規
HoverCardRootのenableTouchプロパティ。デフォルトはfalseです(準備済みソースsrc/HoverCard/HoverCardRoot.vue:15) - 新規
DateFieldRootのstepSnappingプロパティ。デフォルトはfalseです(準備済みソースsrc/DateField/DateFieldRoot.vue:57) - 新規
TreeItemのdisabledプロパティ(2.10.0):https://github.com/unovue/reka-ui/releases/tag/v2.10.0 - 新規
TabsIndicatorが--reka-tabs-indicator-size、--reka-tabs-indicator-thickness、--reka-tabs-indicator-positionの CSS 変数を公開します(準備済みソースsrc/Tabs/TabsIndicator.vue:73-75) useEmitAsPropsとuseForwardPropsEmitsの型推論が改善されました(2.10.0)- 新規
Autocompleteコンポーネント(2.9.0)。専用のAutocomplete*パーツファミリーを備えた、Combobox スタイルの入力です。ドキュメント:https://reka-ui.com/docs/components/autocomplete - 新規 Color プリミティブ(2.9.0):
ColorArea*、ColorField*、ColorSlider*、ColorSwatch、ColorSwatchPicker*。色の解析/変換ユーティリティもルートからエクスポートされます - 新規
TimeRangeField(2.9.0):TimeRangeFieldRoot、TimeRangeFieldInput - 新規 Month および Year ピッカー(2.9.0):
MonthPicker*、YearPicker*、MonthRangePicker*、YearRangePicker*の各ファミリー - 新規
CheckboxRoot/SwitchRootのカスタム boolean 値:trueValueおよびfalseValueプロパティで、固定のtrue/falseを置き換えます(準備済みソースsrc/Checkbox/CheckboxRoot.vue:27-31) - 新規
DropdownMenuFilterパーツ。検索可能なドロップダウンメニューに対応します(2.9.0) - 新規
Splitterのピクセル単位のサイズ指定と制約(2.9.0) - 新規
TooltipProviderによるグローバルなツールチップコンテンツの設定(2.9.0) reka-ui/internalからメニューの内部機能をエクスポートします。不安定な機能であり、セマンティックバージョニングに従わず変更される可能性があります(準備済みソースsrc/internal.ts:1-7)
古いコードを扱う際に、引き続き関係する以前の破壊的変更:
radix-vueはreka-uiに名称変更されました。CSS 変数のプレフィックスは--reka-に、データ属性はdata-reka-になりました。移行ガイド:https://reka-ui.com/docs/guides/migration- Combobox のリファクタリング:
filterFunctionプロパティは削除され、searchTermとdisplayValueは Root からComboboxInputに移動しました(上記の移行ガイドを参照) Checkbox、Toggle、MenuCheckboxItemは、v-model:checked/v-model:pressedではなく標準のv-modelを使用します(上記の移行ガイドを参照)PaginationRootのitemsPerPageは必須です(上記の移行ガイドを参照)- Calendar/DatePicker の
weekStartsOnは、2.8.0 以降ロケールに依存しません:https://github.com/unovue/reka-ui/releases/tag/v2.8.0
リリース一覧:https://github.com/unovue/reka-ui/releases
ベストプラクティス
asChildで合成します。Reka のプリミティブを独自の要素またはコンポーネントとしてレンダリングしながら、動作とアクセシビリティを維持できます(https://reka-ui.com/docs/guides/composition)
<TooltipTrigger asChild>
<MyButton>Hover me</MyButton>
</TooltipTrigger>
useForwardPropsEmitsでラッパーを作成すると、すべての props と emits がプリミティブに渡されます(https://reka-ui.com/docs/utilities/use-forward-props-emits)
const props = defineProps<AccordionRootProps>()
const emits = defineEmits<AccordionRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
// <AccordionRoot v-bind="forwarded">
- アプリを
ConfigProviderでラップし、dir(RTL)、locale、scrollBody、teleportToのデフォルト値を設定します(https://reka-ui.com/docs/utilities/config-provider)
<ConfigProvider dir="rtl" :scroll-body="false">
<App />
</ConfigProvider>
- フラグメント(複数ルート)コンポーネントでは
useForwardExposeを使用し、テンプレート参照が対象の DOM 要素を返すようにします(https://reka-ui.com/docs/utilities/use-forward-expose)
const { forwardRef } = useForwardExpose()
// <div :ref="forwardRef">...</div>
- クラスの切り替えではなく
data-state属性で状態をスタイル設定します。スコープ付きスタイルでテレポートされたコンテンツを扱う場合は:deep()を使用します(https://reka-ui.com/docs/guides/styling)
.AccordionItem[data-state="open"] { border-bottom-width: 2px; }
- コンテンツ部分に
force-mountを追加してアンマウントを自分で制御し、<Transition>でアニメーションを付けます(https://reka-ui.com/docs/guides/animation)
<Transition name="fade">
<DialogContent force-mount>...</DialogContent>
</Transition>
- 長いリストは
ComboboxVirtualizer、ListboxVirtualizer、AutocompleteVirtualizer、またはTreeVirtualizerで仮想化します。スクロールコンテナーには固定の高さを指定します(https://reka-ui.com/docs/guides/virtualization)
<ComboboxViewport class="max-h-80 overflow-y-auto">
<ComboboxVirtualizer :options="items" :estimate-size="25" v-slot="{ option }">
<ComboboxItem :value="option">{{ option.label }}</ComboboxItem>
</ComboboxVirtualizer>
</ComboboxViewport>
-
injectAccordionRootContextなどのinjectXContext関数を使うと、カスタム子要素からプリミティブの内部状態にアクセスできます(https://reka-ui.com/docs/guides/inject-context) -
Reka UI の
useIdは、渡された決定論的な ID、ConfigProviderのuseIdソース、Vue のネイティブuseId(Vue 3.5 以降)、カウンターによるフォールバックの順に解決します(準備済みのソースsrc/shared/useId.ts:26-34)。Vue 3.5 未満の Nuxt では、水和時の ID の不一致を避けるため、Nuxt のuseIdをConfigProvider経由で渡してください(https://reka-ui.com/docs/guides/server-side-rendering) -
日付・時刻コンポーネントには、生の文字列ではなく、
@internationalized/date(直接依存関係)のDateValueオブジェクトとTimeValueオブジェクトを渡します(https://reka-ui.com/docs/guides/dates)
よくある注意点
- すべてのパーツは Root の下に配置する必要があります。ほとんどのコンポーネントでは、正しい重なり順にするため、
*Contentを*PortalまたはTeleportの中に配置する必要もあります。 PresenceのforceMountは、開閉状態にかかわらずコンテンツをレンダリングします。たとえば:hiddenを使って、表示状態は自分で制御してください(https://reka-ui.com/docs/utilities/presence)。- 非表示のフォームフィールドでは、パーツの
nameおよびvalueprops を使用します。SelectRootは空の状態に対してnullableValueも受け付けます。 - ツリーシェイキングには
reka-uiからインポートし、Dialog.Rootのようにパーツをグループ化して使う場合はreka-ui/namespacedからインポートします。統合を参照してください。