GithubHelp home page GithubHelp logo

prabhuignoto / vue-float-menu Goto Github PK

View Code? Open in Web Editor NEW
562.0 8.0 30.0 10.46 MB

🎈Customizable floating menu for Vue

Home Page: https://vue-float-menu.prabhuignoto.vercel.app

License: MIT License

JavaScript 2.85% HTML 1.04% Vue 74.44% CSS 0.60% SCSS 7.59% TypeScript 13.39% Shell 0.10%
menu vue3 float-menu vue-component vue-menu drag-menu composition-api vue nested-menus typescript

vue-float-menu's Introduction


Build Status Maintainability DeepScan grade DeepSource Snyk Vulnerabilities for GitHub Repo minified Depfu

✨ Features

  • πŸ‘Œ Β Drag and place the menu anywhere on screen.
  • πŸ‘“ The smart menu system detects the edges of the screen and flips the menu automatically.
  • πŸ‘ Support for nested menus.
  • ⌨ Keyboard Accessible.
  • 🌈 Support for custom themes.
  • πŸ’ͺ Built with Typescript.
  • 🧰 Intuitive API with data driven behavior.
  • 🌠 Built with the all new Vue 3.

Table of Contents

⚑ Installation

pnpm install vue-float-menu

πŸš€ Getting Started

vue-float-menu has some great defaults. Please check the props section for all available options.

vue-float-menu finds the optimal menu orientation depending on the position of the menu. for e.g if the menu is placed at the bottom edge and the orientation set to bottom, the component will automatically flip the orientation to top.

Here is a basic example that sets the default position of the menu as top left.

<template>
  <float-menu
    :position="'top left'"
    :dimension="50"
    :menu-data="items"
    :on-selected="handleSelection"
  >
    Drag
  </float-menu>
</template>

<script>
import { FloatMenu } from "vue-float-menu";
import "vue-float-menu/dist/vue-float-menu.css";

export default {
  components: {
    FloatMenu,
  },
  setup() {
    const handleSelection = (selectedItem) => {
      console.log(selectedItem);
    };
    return {
      handleSelection,
    };
  },
  data() {
    return {
      items: [
        { name: "New" },
        {
          name: "Edit",
          subMenu: {
            name: "edit-items",
            items: [{ name: "Copy" }, { name: "Paste" }],
          },
        },
        {
          name: "Open Recent"
        },
        {
          name: "Save",
        }
      ],
    };
  },
};
</script>

Props

Prop Type Description
dimension number dimension of the Menu Head width x height in pixels.
position String initial position of the Menu Head. can be any one of the values top left, top right, bottom left, bottom right
fixed Boolean disables dragging and the menu will be fixed. use the position prop to fix the menu position
menu-dimension Object sets the width and minimum height of the Menu.
menu-data Object data to generate the menu. refer to populating the menu for usage details.
on-selected Function hook that is called on selection.
menu-style String can be slide-out or accordion.slide-out is the default menu style.
flip-on-edges Boolean flips the menu content on the right edges of the screen.
theme Object prop to customize the color schemes. refer theme for usage.

Position

The position prop can be used to set the initial position of the Menu Head. The prop can accept any one of the following values.

  • top left (default)
  • top right
  • bottom left
  • bottom right
  <float-menu :dimension=50 position="bottom right">
    <template #icon>
      <BoxIcon />
    </template>
  </float-menu>

Menu head dimension

dimension prop can be used to set the width and height of the menu head. The prop takes a single number value to set the height and width of the Menu Head.

  <float-menu :dimension=50>
    <template #icon>
      <BoxIcon />
    </template>
  </float-menu>

Menu dimension

prop to set the height and width of the menu.

  <float-menu
    :dimension=50
    :menu-dimension="{height: 400, width: 300}"
    position="bottom right"
  >
    <template #icon>
      <BoxIcon />
    </template>
  </float-menu>

Menu Style

The component supports two modes slide-out(default) and accordion. The accordion style is more suitable for mobile devices.

  <float-menu
    position="bottom right"
    flip-on-edges
    menu-style="accordion"
  >
    <template #icon>
      <BoxIcon />
    </template>
  </float-menu>

accordion

Populating the Menu

Use the menu-data prop to create simple or nested menus of your liking. menu-data takes an array of MenuItem type

MenuItem properties

property description
name display name of the menu item.
subMenu data for the sub-menu
disabled disables the menu item
divider makes the item as a divider

Here we create a simple Menu structure with 3 Menu items with no sub menus.

const menuData = [
  { name: "New" },
  {
    name: "Edit",
    subMenu: {
      name: "edit-items",
      items: [{ name: "Copy" }, { name: "Paste", disabled: true }],
    },
  },
  {divider: true},
  {
    name: "Open Recent",
    subMenu: {
      name: "recent-items",
      items: [{ name: "Document 1" }, {divider: true}, { name: "Document 2" }],
    },
  },
]
  <float-menu
    :dimension=50
    :menu-dimension="{height: 400, width: 300}"
    :menu-data="menuData"
    position="bottom right"
  >
    <BoxIcon />
  </float-menu>

on-select

hook for the menu item selection event.

  <float-menu
    :dimension=50
    position="bottom right"
    :menu-dimension="{height: 400, width: 300}"
    :menu-data="{items: [{name: 'File'}, {name: 'Open'}]}"
    on-select="handleSelection"
  >
    <BoxIcon />
  </float-menu>

Flip on edges

setting this prop flips the menu content on the right edges of the screen.

  <float-menu
    :dimension=50
    position="bottom right"
    flip-on-edges
    on-select="handleSelection"
  >
    <BoxIcon />
  </float-menu>

flip

Fixed Menu

To disable dragging and to fix the position statically, set fixed to true. This prop is disabled by default. Use this prop along with the position prop to set the desired position.

  <float-menu :dimension=50 position="bottom right" fixed>
    <template #icon>
      <BoxIcon />
    </template>
  </float-menu>

🎨 Custom icon

To customize the Menu Icon, simply pass any content in between the float-menu tags. Here we render a custom icon.

  <float-menu
    :dimension=50
    :menu-data="menuData"
  >
    <template #icon>
      <BoxIcon />
    </template>
  </float-menu>

and here we render a text Click inside the Menu handle

  <float-menu
    :dimension=50
    :menu-data="menuData"
  >
    Click
  </float-menu>

example2

🎭 Icon support

Each menu item can be iconified and the component uses slots to inject the icons.

Pass individual icons (or images) as templates marked with a unique slot id. please make sure the ids match the iconSlot property in the items array.

<float-menu
  :menu-data="items"
>
  <template #new>
    <img
      src="../assets/new.svg"
      alt="new"
    >
  </template>
  <template #edit>
    <img
      src="../assets/edit.svg"
      alt="edit"
    >
  </template>
</float-menu>

export default defineComponent({
  name: "MenuExample",
  data()  {
    return {
      items: [
        { name: "New File", iconSlot: "new" },
        { name: "New Window", iconSlot: "edit" },
      ]
    }
  }
})

menu-icon

This works seamlessly even for nested menu structure. Make sure the slot ids match and the component will render the icons appropriately.

<float-menu
  :menu-data="items"
>
  <template #cut>
    <img
      src="../assets/window-maximize.svg"
      alt="cut"
    >
  </template>
</float-menu>

export default defineComponent({
  name: "MenuExample",
  data()  {
    return {
      items: [
        { name: "edit",
        subMenu: [{ name: "cut", iconSlot: "cut" }]},
      ]
    }
  }
});

🌈 Theme

Customize the color schemes with the theme prop.

  <float-menu
    :dimension=50
    :theme="{
      primary: '#00539C',
      textColor: '#000',
      menuBgColor: '#fff',
      textSelectedColor: '#fff',
    }"
  >
    Click
  </float-menu>

πŸ“¦ Build Setup

# install dependencies
pnpm install

# start dev
pnpm run dev

# run css linting
pnpm run lint:css

# lint everything
pnpm run lint:all

# package lib
npm run rollup

πŸ”¨ Contributing

  1. Fork it ( https://github.com/prabhuignoto/vue-float-menu/fork )
  2. Create your feature branch (git checkout -b new-feature)
  3. Commit your changes (git commit -am 'Add feature')
  4. Push to the branch (git push origin new-feature)
  5. Create a new Pull Request

🧱 Built with

Notes

  • The project uses vite instead of @vue/cli. I choose vite for speed and i also believe vite will be the future.

Meta

Prabhu Murthy – @prabhumurthy2 – [email protected]

https://www.prabhumurthy.com

Distributed under the MIT license. See LICENSE for more information.

https://github.com/prabhuingoto/

vue-float-menu's People

Contributors

deepsourcebot avatar imgbotapp avatar kodiakhq[bot] avatar prabhuignoto avatar restyled-commits avatar tincann 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  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  avatar  avatar

vue-float-menu's Issues

keep menu open?

is it possible to keep the menu open when clicked outside?
I am looking for a way to close the menu only when the open button is clicked again

Sub-Menu not opening first attempt

This is a phenomenal component, thank you for this!

The first time I click to open the menu, all looks fine until I click on a sub menu. Nothing happens. After closing the menu and re-opening it however, everything works as intended.

how do I control font size, behavior, etc.?

I don't know how to control or style anything. The menu text is extremely tiny. I have The position fixed but when I click on the header it jumps to the left over my other icons. Can anyone help?

reduce build size

the component depends on interactjs and this causes a sizable increase in the final build size.
check to include only @interactjs/interactjs module and discard the unused functionality or a find an alternative solution.

TypeError: Cannot read properties of null (reading 'key')

When I click on a menu item, I get the following error & stack trace, & the on-select="handleSelection" function never works:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'key')
    at renderSlot (runtime-core.esm-bundler.js:2969:57)
    at vue-float-menu.es.js:1:18216
    at renderFnWithContext (runtime-core.esm-bundler.js:853:21)
    at renderSlot (runtime-core.esm-bundler.js:2968:55)
    at vue-float-menu.es.js:1:6819
    at renderFnWithContext (runtime-core.esm-bundler.js:853:21)
    at normalizeChildren (runtime-core.esm-bundler.js:6925:42)
    at createBaseVNode (runtime-core.esm-bundler.js:6678:9)
    at _createVNode (runtime-core.esm-bundler.js:6780:12)
    at createVNodeWithArgsTransform (runtime-core.esm-bundler.js:6636:12)

Here is my configuration:

<script setup>
  import { FloatMenu } from "vue-float-menu";
  import "vue-float-menu/dist/vue-float-menu.css";

  // Floating menu data.
  const menuData = [
    { name: "Dashboard" },
    {
      name: "Edit",
      subMenu: {
        name: "edit-items",
        items: [{ name: "Copy" }, { name: "Paste", disabled: true }],
      },
    },
    {divider: true},
    {
      name: "Open Recent",
      subMenu: {
        name: "recent-items",
        items: [{ name: "Document 1" }, {divider: true}, { name: "Document 2" }],
      },
    },
  ];

  const handleSelection = (selectedItem) => {
    console.log(selectedItem);
  };

</script>
<template>
  <float-menu
    :dimension=50
    :menu-dimension="{height: 400, width: 300}"
    :menu-data="menuData"
    position="bottom right"
    on-select="handleSelection"
  >
    <i class="fa-solid fa-bars"></i>
  </float-menu>
</template>

Vue 3 plus Vite.

Vue warn: Failed to resolve component: Menu

Thank you for this great package.
I followed the code according to the example.
Here's the package.json snippet

...
 "@intlify/vite-plugin-vue-i18n": "^3.2.1",
    "@mdi/js": "^5.9.55",
    "@vitejs/plugin-vue": "^1.10.1",
    "axios": "^0.21.1",
    "dayjs": "^1.10.7",
    "mdi-vue": "^3.0.7",
    "tailwindcss": "^2.2.8",
    "vite": "^2.6.14",
    "vue": "^3.2.4",
    "vue-float-menu": "^1.9.1",
    "vue-i18n": "^9.1.7",
    "vue-router": "4",
    "vue-tippy": "^6.0.0-alpha.32",
...

The following warning appears every time I click the floating button
image

image
Do I simply ignore it or ?

Since I'm using Vitejs, I followed the guide on the following page to fix it : vueCompilerOptions on Vite 2 #1312

plugins: [
   vue({
      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('float-') // float-menu
            || tag.startsWith('custom-') // my custom component
            || tag.startsWith('famous-') // my other component
        }
      }
    }),
    vueI18n({
      include: path.resolve(__dirname, './src/locales/**'),
    }),
  ],

And the result, the floating button can't be clicked at all.
Any help given will be greatly appreciated. Thanks

Depfu Error: No dependency files found

Hello,

We've tried to activate or update your repository on Depfu and couldn't find any supported dependency files. If we were to guess, we would say that this is not actually a project Depfu supports and has probably been activated by error.

Monorepos

Please note that Depfu currently only searches for your dependency files in the root folder. We do support monorepos and non-root files, but don't auto-detect them. If that's the case with this repo, please send us a quick email with the folder you want Depfu to work on and we'll set it up right away!

How to deactivate the project

  • Go to the Settings page of either your own account or the organization you've used
  • Go to "Installed Integrations"
  • Click the "Configure" button on the Depfu integration
  • Remove this repo (prabhuignoto/vue-float-menu) from the list of accessible repos.

Please note that using the "All Repositories" setting doesn't make a lot of sense with Depfu.

If you think that this is a mistake

Please let us know by sending an email to [email protected].


This is an automated issue by Depfu. You're getting it because someone configured Depfu to automatically update dependencies on this project.

Is it possible to use it with Nuxt?

Hi there
Thank you for sharing this excelent Vue component. It looks so useful and flexible!
As I'm starting to build a website using Nuxt, I wonder if would be possible to use vue-float-menu with it. Maybe with the help of nuxt-composition-api. I'm not savvy enough to find a way by myself.

best regards,
Gil

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.