Skip to content
This repository was archived by the owner on Feb 14, 2025. It is now read-only.
/ vue-kbar Public archive

Extensible command+k interface for Vue 3 applications. Inspired by timc1/kbar.

License

Notifications You must be signed in to change notification settings

bytebase/vue-kbar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

5281203 · Feb 11, 2025

History

82 Commits
Sep 6, 2022
Nov 30, 2021
May 6, 2022
Sep 8, 2022
Nov 30, 2021
Nov 30, 2021
Apr 29, 2022
Apr 20, 2022
Apr 19, 2022
Mar 17, 2022
Dec 2, 2021
Mar 20, 2022
Aug 3, 2023
Aug 3, 2023
Dec 2, 2021
Dec 2, 2021

Repository files navigation

vue-kbar

Extensible command+k interface for Vue 3 applications. Inspired by timc1/kbar.

Caution! This is still WIP.

Screenshots

TBD

How to use

1. Install dependency

# npm install --save @bytebase/vue-kbar

or if you are using yarn

# yarn add @bytebase/vue-kbar

2. Import core components

// App.vue

import {
  KBarProvider,
  KBarPortal,
  KBarPositioner,
  KBarAnimator,
  KBarSearch,
  createAction,
} from "@bytebase/vue-kbar";

3. Define global actions

// App.vue

// use `createAction` as a type definition helper
const globalActions = [
  createAction({
    id: "home",
    name: "Home",
    shortcut: ["g", "h"],
    section: "Navigation",
    subtitle: "Go back to home",
    perform: () => router.push("/"),
  }),
  createAction({
    id: "docs",
    name: "Docs",
    shortcut: ["g", "d"],
    section: "Navigation",
    perform: () => router.push("/docs"),
  }),
];

4. Use core components

You need to wrap your Vue app entrance by vue-kbar core components.

vue-kbar comes with no out-of-the-box styles. You may specify styles according to your application's UI design. Here is an example of using tailwindcss.

<KBarProvider :actions="globalActions">
  <KBarPortal>
    <KBarPositioner class="bg-gray-300 bg-opacity-80">
      <KBarAnimator
        class="bg-white shadow-lg rounded-lg w-128 overflow-hidden divide-y"
      >
        <KBarSearch
          class="px-3 py-4 text-lg w-full box-border outline-none border-none"
        />
        <MyResultsRenderer />
        <!-- see below -->
      </KBarAnimator>
    </KBarPositioner>
  </KBarPortal>

  <!-- you application entrance here -->
  <MyApp />
</KBarProvider>

5. Implement a results renderer

vue-kbar doesn't render results it self. You may render results with your components and styles.

Here is a simple example of how to implement <MyResultsRenderer /> above.

// MyResultsRenderer.vue

<KBarResults
  :items="matches.results"
  :item-height="itemHeight"
  class="max-h-96"
>
  <!-- KBarResults creates a virtual list to manage mass of actions -->
  <!-- It also reacts to up/down/enter keystroke for activeIndex management -->
  <!-- You still may use your own component if you really want to customize the result list -->
  <template #item="{ item, index, active }">
    <div v-if="typeof item === 'string'" class="section">
      <!-- string items are section headers -->
      <!-- now we just render them as plain texts -->
      {{ item }}
    </div>
    <div v-else class="item" :class="{ active }">
      <!-- render featured actions -->
      <div class="main">{{ item.name }}</div>
      <span v-if="item.subtitle" class="subtitle"> {{ item.subtitle }} </span>
    </div>
  </template>
</KBarResults>
// MyResultsRenderer.vue

import { useKBarMatches, KBarResults } from "@bytebase/vue-kbar";

export default {
  name: "MyResultsRenderer",
  components: { KBarResults },
  setup() {
    // Visit the latest matches
    const matches = useKBarMatches();

    // Tell KBarResults the height of each item will be rendered
    const itemHeight = (params: { item: any; index: number }) => {
      if (typeof params.item === "string") return 32;
      return 64;
    };

    return { matches, itemHeight };
  },
};

6. Register actions dynamically

You may register actions dynamically by calling useRegisterActions in any descendant component of <KBarProvider>. This hook method is reactive and bound to the component's life cycle, so you don't need to refresh or unregister manually. Here is an example.

// SomeComponent.vue

import { useRegisterActions, createAction } from "@bytebase/vue-kbar";

export default {
  name: "SomeComponent",
  setup() {
    // Maybe you've already used some auto-fetch stuff to
    // update the `posts` automatically
    const posts = useFetch("/your-api", [deps]);

    // Mapping posts to actions as a computed
    const actions = computed(() =>
      posts.map((post) =>
        createAction({
          id: `to-detail-${post.id}`,
          name: post.title,
          subtitle: post.abstract,
          section: "Posts",
          perform: () => router.push(`/post/${post.id}`),
        })
      )
    );

    // Dynamically register actions
    // pass `prepend: true` to make them listed before global actions
    // When `actions` changed, they will be automatically re-registered
    useRegisterActions(actions, true);
  },
};

About

Extensible command+k interface for Vue 3 applications. Inspired by timc1/kbar.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published