1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UIを作成する時フレームワークを使ったことはありますか?

私はCSSフレームワークのtailwindを多用していて、そのtailwindからUIコンポーネントが出ていたので使ってみました。

HeadlessUIとは

Headless Componentと言われ、tailwindから出ているUIの制御や動作だけを行ってくれるものです。なのでデザイン等は自身でしていく必要があるので、CSSやtailwind等のフレームワーク自由に組みわせてUIを作っていきます。

使用感

ReactとVueでの使い方が公式に乗っているのでVueの方を参考にしつつ、私なりの独断と偏見で使用感を書きたいと思います。

インストールの手順については省略しております。
皆様のほうでお調べください

コンポーネントについて

Vueの方では10個のコンポーネントが用意されていて、特に便利だと感じた3つを紹介したいと思います。

Tabs

tabs.vue
<script setup>
    import { TabGroup, TabList, Tab, TabPanels, TabPanel } from "@headlessui/vue";
    import Chat from "@/components/Chat.vue";
    import Todo from "@/components/Todo.vue";
    import Blog from "@/components/Blog.vue";
    import User from "@/components/User.vue";
    import Janken from "@/components/Janken.vue";
    import Test from "@/components/Test.vue";
    
    const menus = [
        { icon: "/src/assets/chat.svg", component: Chat, title: "Chat" },
        { icon: "/src/assets/todo.svg", component: Todo, title: "Todo" },
        { icon: "/src/assets/book.svg", component: Blog, title: "Blog" },
        { icon: "/src/assets/user.svg", component: User, title: "User" },
        { icon: "/src/assets/janken.svg", component: Janken, title: "Janken" },
        { icon: "/src/assets/test.svg", component: Test, title: "Test" },
    ]
</script>

<template>
    <TabGroup>
        <TabList class="w-full sticky flex gap-5 top-10">
            <Tab v-for="menu in menus">
                <img :src="menu.icon" alt="" width="25" height="25">
            </Tab>
        </TabList>
        <TabPanels class="w-full h-full">
            <TabPanel v-for="menu in menus" class="w-full h-full">
                <p class="text-3xl text-center">{{ menu.title }}</p>
                <component :is="menu.component" />
            </TabPanel>
        </TabPanels>
    </TabGroup>
</template>

tabs.gif

タブを縦にしたり、選択されているタブのスタイルを変更することもできます。

Switch(Toggle)

公式からの引用です

switch.vue
<template>
  <Switch
    v-model="enabled"
    :class="enabled ? 'bg-blue-600' : 'bg-gray-200'"
    class="relative inline-flex h-6 w-11 items-center rounded-full"
  >
    <span class="sr-only">Enable notifications</span>
    <span
      :class="enabled ? 'translate-x-6' : 'translate-x-1'"
      class="inline-block h-4 w-4 transform rounded-full bg-white transition"
    />
  </Switch>
</template>

<script setup>
  import { ref } from 'vue'
  import { Switch } from '@headlessui/vue'

  const enabled = ref(false)
</script>

switch3.gif

こういうのがサクッと作れるのは良いですね

Dialog(Modal)

dialog.vue
    <TransitionRoot appear :show="isOpen" as="template">
        <Dialog as="div" @close="closeModal" class="relative z-10">
            <TransitionChild
                as="template"
                enter="duration-300 ease-out"
                enter-from="opacity-0"
                enter-to="opacity-100"
                leave="duration-200 ease-in"
                leave-from="opacity-100"
                leave-to="opacity-0"
            >
                <div class="fixed inset-0 bg-black/25" />
            </TransitionChild>
            <div class="fixed inset-0 overflow-y-auto">
                <div
                    class="flex min-h-full items-center justify-center p-4 text-center"
                >
                    <TransitionChild
                        as="template"
                        enter="duration-300 ease-out"
                        enter-from="opacity-0 scale-95"
                        enter-to="opacity-100 scale-100"
                        leave="duration-200 ease-in"
                        leave-from="opacity-100 scale-100"
                        leave-to="opacity-0 scale-95"
                    >
                        <DialogPanel
                            class="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all"
                        >
                            <DialogTitle
                                as="h3"
                                class="text-lg font-medium leading-6 text-gray-900"
                            >
                            投稿
                            </DialogTitle>
                            <div class="mt-2">
                                <input type="text" v-model="title" class="w-full h-8" placeholder="タイトル">
                            </div>
                            <div class="mt-2">
                                <textarea placeholder="本文" v-model="body" class="w-full h-32 resize-none"></textarea>
                            </div>
                            <div class="mt-4 flex gap-20 justify-center">
                                <button
                                    type="button"
                                    class="inline-flex justify-center rounded-md border border-transparent bg-red-100 px-4 py-2 text-sm font-medium text-red-900 hover:bg-red-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-2"
                                    @click="closeModal"
                                >
                                キャンセル
                                </button>
                                <button
                                    type="button"
                                    class="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
                                    @click="post"
                                >
                                投稿
                                </button>
                            </div>
                        </DialogPanel>
                    </TransitionChild>
                </div>
            </div>
        </Dialog>
    </TransitionRoot>

dialog.gif

背景の色やダイヤログを開いた時、閉じた時にイベントを発生させることも可能です。

まとめ

HeadlessUIを使うことでUIの制御や動作を任せる事ができるので、デザインの方に時間を割くことができ、よりクリエイティブなデザインにすることができると感じました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?