Giter VIP home page Giter VIP logo

vue-kbar's Introduction

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);
  },
};

vue-kbar's People

Contributors

boojack avatar d-bytebase avatar dependabot[bot] avatar liuji-jim avatar renovate[bot] avatar tianzhou avatar titouanmathis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vue-kbar's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency slug to v8
  • chore(deps): update dependency vite to v3
  • chore(deps): update github/codeql-action action to v2
  • fix(deps): update dependency @vueuse/core to v9
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/codeql-analysis.yml
  • actions/checkout v2
  • github/codeql-action v1
  • github/codeql-action v1
  • github/codeql-action v1
npm
package.json
  • @vueuse/core ^7.1.2
  • match-sorter ^6.3.1
  • tiny-invariant ^1.2.0
  • @typescript-eslint/eslint-plugin 5.36.2
  • @typescript-eslint/parser 5.36.2
  • @vitejs/plugin-vue 1.10.2
  • @vue/eslint-config-typescript 9.1.0
  • eslint 8.23.0
  • eslint-config-prettier 8.5.0
  • eslint-formatter-summary 1.1.0
  • eslint-plugin-prettier 4.2.1
  • eslint-plugin-vue 8.7.1
  • pinia 2.0.22
  • prettier 2.7.1
  • rimraf 3.0.2
  • rollup 2.79.0
  • rollup-plugin-visualizer 5.8.1
  • slug 5.3.0
  • typescript 4.8.2
  • vite 2.9.15
  • vitepress 0.22.4
  • vue 3.2.38
  • vue-tsc 0.40.7
  • vue ^3.2.33

  • Check this box to trigger a request for Renovate to run again on this repository

Roadmap?

Hi!

Thanks for starting this awesome project! I did a bit of research on what's available when it comes to command palette-type things suited for development with Vue.

This came up, along with a very few other projects (notably https://github.com/ssleptsov/ninja-keys, which seems nice, but is probably less extensive than kbar).

Before going further: you list this as WIP - do you see it as more or less usable in its current state, and how do you see the project's future?

[Feature request] Expose `visible` computed property from useKBarState

Hi there,

Thank you very much for your amazing work. I have a request to simplify the usage of useKBarState.

If we want to open the KBar manually, we have to create computed and methods.

It would be great to be provided with a set of computed and methods out of the box.

Current situation

const state = useKBarState();
const visible = computed(() => state.value.visibility !== "hidden");
const open = () => { state.value.visibility = "visible" }
const close = () => { state.value.visibility = "hidden" }

return { visible, open, close }

Ideally

const { visible, open, close } = useKBarState();

return { visible, open, close }

What do you think ๐Ÿค”

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.