diff --git a/.eslintignore b/.eslintignore index 84d88d5c..f10b7e32 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,3 @@ -demos +demo *.d.ts cache diff --git a/CHANGELOG.md b/CHANGELOG.md index a51e0546..b1666096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,162 @@ # Changelog +## v5.2.2 + + +### 🩹 Fixes + + - V-close-popper directive, #1022 (#1022) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) + +## v5.2.1 + + +### 🚀 Enhancements + + - Add deprecation notice to VTooltip and VClosePopper (abf094f) + +### 🩹 Fixes + + - Revert autohide on mousedown, add autoHideOnMousedown in config, fix #1015 (#1015) + - Watch triggers array deeply, fix #1018 (#1018) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) + +## v5.2.0 + + +### 🚀 Enhancements + + - Expose global `recomputeAllPoppers` helper (#1010) + +### ❤️ Contributors + +- Anthony Fu + +## v5.1.1 + + +### 🩹 Fixes + + - Fix v-close-popper to function on mousedown (#1014) + +### ❤️ Contributors + +- Giannis Koutsaftakis ([@kouts](http://github.com/kouts)) + +## v5.1.0 + + +### 🚀 Enhancements + + - Close on mousedown (89258a9) + +### 💅 Refactors + + - Improve types (#1011) + +### 🏡 Chore + + - Remove vue2 demo (#1009) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) +- Anthony Fu + +## v5.0.3 + + +### 🩹 Fixes + + - Set default disposeTimeout to default transition duration (18e786c) + +### 📖 Documentation + + - Import directly (fa626ac) + - Upgrade vitepress + search (5a46278) + - Enable search detailed view by default (3175a62) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) + +## v5.0.2 + + +### 🩹 Fixes + + - **menu:** Don't close on popper blur (74b940f) + +### 🌊 Types + + - Improved props types (5bf9b74) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) + +## v5.0.1 + + +### 🩹 Fixes + + - `Element' is not defined on server (47eb20c) + +### 📖 Documentation + + - Update to v5 (44d0108) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) + +## v5.0.0 + +Bumping the version to prevent issues with tags from vue-tooltip v3 and v4 in the repository. + +No changes compared to floating-vue v2.0.0 + +## v2.0.0 + + +### 🚀 Enhancements + + - Export vTooltip and vClosePopper for script setup usage (16b3a9b) + - Remove dispose event (4be2062) + +### 🩹 Fixes + + - Import nuxt composables from #imports (#998) + - Change default disposeTimeout to 0 (0699bf8) + +### 💅 Refactors + + - Default components are now simple ts files (6439fce) + +### 📖 Documentation + + - Fixed spelling mistake in migration v2 docs (#983) + +### 🌊 Types + + - Props and events (ee27b15) + +### ✅ Tests + + - **lint:** Fix (942a360) + +### ❤️ Contributors + +- Guillaume Chau ([@Akryum](http://github.com/Akryum)) +- Yahlieel Jafta +- Daniel Roe + ## v2.0.0-beta.24 diff --git a/README.md b/README.md index ab935d20..14749cdf 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ New versions: |Old|New|Target |---|---|---| |v-tooltip v3|floating-vue v1|Vue 2| -|v-tooltip v4|floating-vue v2|Vue 3| +|v-tooltip v4|floating-vue v5|Vue 3| [💚️ Become a Sponsor](https://github.com/sponsors/Akryum) diff --git a/demos/demo-vue3/.eslintrc.js b/demo/.eslintrc.js similarity index 100% rename from demos/demo-vue3/.eslintrc.js rename to demo/.eslintrc.js diff --git a/demos/demo-vue3/.gitignore b/demo/.gitignore similarity index 100% rename from demos/demo-vue3/.gitignore rename to demo/.gitignore diff --git a/demos/demo-vue3/README.md b/demo/README.md similarity index 100% rename from demos/demo-vue3/README.md rename to demo/README.md diff --git a/demos/demo-vue3/cypress.json b/demo/cypress.json similarity index 100% rename from demos/demo-vue3/cypress.json rename to demo/cypress.json diff --git a/demos/demo-vue3/index.html b/demo/index.html similarity index 100% rename from demos/demo-vue3/index.html rename to demo/index.html diff --git a/demos/demo-vue3/package.json b/demo/package.json similarity index 55% rename from demos/demo-vue3/package.json rename to demo/package.json index f03063d5..e9b37f94 100644 --- a/demos/demo-vue3/package.json +++ b/demo/package.json @@ -9,26 +9,26 @@ "lint": "eslint . --ext .js,.vue" }, "dependencies": { - "core-js": "^3.30.2", + "core-js": "^3.35.0", "floating-vue": "workspace:*", - "vue": "^3.3.4", - "vue-router": "^4.2.1" + "vue": "^3.4.13", + "vue-router": "^4.2.5" }, "devDependencies": { - "@vitejs/plugin-vue": "^4.2.3", - "@vue/compiler-sfc": "^3.3.4", + "@vitejs/plugin-vue": "^5.0.3", + "@vue/compiler-sfc": "^3.4.13", "@vue/eslint-config-standard": "^8.0.1", - "autoprefixer": "^10.4.14", + "autoprefixer": "^10.4.16", "babel-eslint": "^10.1.0", - "eslint": "^8.41.0", - "eslint-plugin-cypress": "^2.13.3", - "eslint-plugin-import": "^2.27.5", + "eslint": "^8.56.0", + "eslint-plugin-cypress": "^2.15.1", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.1.1", "eslint-plugin-standard": "^5.0.0", - "eslint-plugin-vue": "^9.13.0", - "postcss": "^8.4.23", - "tailwindcss": "^3.3.2", - "vite": "^4.3.8" + "eslint-plugin-vue": "^9.20.1", + "postcss": "^8.4.33", + "tailwindcss": "^3.4.1", + "vite": "^5.0.11" } } diff --git a/demos/demo-vue3/postcss.config.js b/demo/postcss.config.js similarity index 100% rename from demos/demo-vue3/postcss.config.js rename to demo/postcss.config.js diff --git a/demos/demo-vue3/public/favicon.ico b/demo/public/favicon.ico similarity index 100% rename from demos/demo-vue3/public/favicon.ico rename to demo/public/favicon.ico diff --git a/demos/demo-vue3/public/index.html b/demo/public/index.html similarity index 100% rename from demos/demo-vue3/public/index.html rename to demo/public/index.html diff --git a/demos/demo-vue3/src/App.vue b/demo/src/App.vue similarity index 100% rename from demos/demo-vue3/src/App.vue rename to demo/src/App.vue diff --git a/demos/demo-vue3/src/assets/logo.png b/demo/src/assets/logo.png similarity index 100% rename from demos/demo-vue3/src/assets/logo.png rename to demo/src/assets/logo.png diff --git a/demos/demo-vue3/src/components/HelloWorld.vue b/demo/src/components/HelloWorld.vue similarity index 100% rename from demos/demo-vue3/src/components/HelloWorld.vue rename to demo/src/components/HelloWorld.vue diff --git a/demos/demo-vue3/src/main.js b/demo/src/main.js similarity index 100% rename from demos/demo-vue3/src/main.js rename to demo/src/main.js diff --git a/demos/demo-vue3/src/router.js b/demo/src/router.js similarity index 100% rename from demos/demo-vue3/src/router.js rename to demo/src/router.js diff --git a/demos/demo-vue3/src/style.css b/demo/src/style.css similarity index 100% rename from demos/demo-vue3/src/style.css rename to demo/src/style.css diff --git a/demos/demo-vue3/src/views/Home.vue b/demo/src/views/Home.vue similarity index 100% rename from demos/demo-vue3/src/views/Home.vue rename to demo/src/views/Home.vue diff --git a/demos/demo-vue3/src/views/component/DropdownDemo1.vue b/demo/src/views/component/DropdownDemo1.vue similarity index 100% rename from demos/demo-vue3/src/views/component/DropdownDemo1.vue rename to demo/src/views/component/DropdownDemo1.vue diff --git a/demos/demo-vue3/src/views/component/DropdownDemo2Manual.vue b/demo/src/views/component/DropdownDemo2Manual.vue similarity index 100% rename from demos/demo-vue3/src/views/component/DropdownDemo2Manual.vue rename to demo/src/views/component/DropdownDemo2Manual.vue diff --git a/demos/demo-vue3/src/views/component/SubMenuDemo1.vue b/demo/src/views/component/SubMenuDemo1.vue similarity index 100% rename from demos/demo-vue3/src/views/component/SubMenuDemo1.vue rename to demo/src/views/component/SubMenuDemo1.vue diff --git a/demos/demo-vue3/src/views/directive/CreateTooltip.vue b/demo/src/views/directive/CreateTooltip.vue similarity index 100% rename from demos/demo-vue3/src/views/directive/CreateTooltip.vue rename to demo/src/views/directive/CreateTooltip.vue diff --git a/demos/demo-vue3/src/views/directive/VTooltipDemo1.vue b/demo/src/views/directive/VTooltipDemo1.vue similarity index 100% rename from demos/demo-vue3/src/views/directive/VTooltipDemo1.vue rename to demo/src/views/directive/VTooltipDemo1.vue diff --git a/demos/demo-vue3/src/views/directive/VTooltipDemo2Html.vue b/demo/src/views/directive/VTooltipDemo2Html.vue similarity index 100% rename from demos/demo-vue3/src/views/directive/VTooltipDemo2Html.vue rename to demo/src/views/directive/VTooltipDemo2Html.vue diff --git a/demos/demo-vue3/src/views/directive/VTooltipDemo3Async.vue b/demo/src/views/directive/VTooltipDemo3Async.vue similarity index 100% rename from demos/demo-vue3/src/views/directive/VTooltipDemo3Async.vue rename to demo/src/views/directive/VTooltipDemo3Async.vue diff --git a/demos/demo-vue3/src/views/directive/VTooltipDemo4Input.vue b/demo/src/views/directive/VTooltipDemo4Input.vue similarity index 100% rename from demos/demo-vue3/src/views/directive/VTooltipDemo4Input.vue rename to demo/src/views/directive/VTooltipDemo4Input.vue diff --git a/demos/demo-vue3/src/views/directive/VTooltipDemo5Manual.vue b/demo/src/views/directive/VTooltipDemo5Manual.vue similarity index 100% rename from demos/demo-vue3/src/views/directive/VTooltipDemo5Manual.vue rename to demo/src/views/directive/VTooltipDemo5Manual.vue diff --git a/demos/demo-vue3/tailwind.config.js b/demo/tailwind.config.js similarity index 100% rename from demos/demo-vue3/tailwind.config.js rename to demo/tailwind.config.js diff --git a/demos/demo-vue3/tests/e2e/.eslintrc.js b/demo/tests/e2e/.eslintrc.js similarity index 100% rename from demos/demo-vue3/tests/e2e/.eslintrc.js rename to demo/tests/e2e/.eslintrc.js diff --git a/demos/demo-vue3/tests/e2e/plugins/index.js b/demo/tests/e2e/plugins/index.js similarity index 100% rename from demos/demo-vue3/tests/e2e/plugins/index.js rename to demo/tests/e2e/plugins/index.js diff --git a/demos/demo-vue3/tests/e2e/specs/test.js b/demo/tests/e2e/specs/test.js similarity index 100% rename from demos/demo-vue3/tests/e2e/specs/test.js rename to demo/tests/e2e/specs/test.js diff --git a/demos/demo-vue3/tests/e2e/support/commands.js b/demo/tests/e2e/support/commands.js similarity index 100% rename from demos/demo-vue3/tests/e2e/support/commands.js rename to demo/tests/e2e/support/commands.js diff --git a/demos/demo-vue3/tests/e2e/support/index.js b/demo/tests/e2e/support/index.js similarity index 100% rename from demos/demo-vue3/tests/e2e/support/index.js rename to demo/tests/e2e/support/index.js diff --git a/demos/demo-vue3/vite.config.ts b/demo/vite.config.ts similarity index 100% rename from demos/demo-vue3/vite.config.ts rename to demo/vite.config.ts diff --git a/demos/demo-vue2/.eslintignore b/demos/demo-vue2/.eslintignore deleted file mode 100644 index b9470778..00000000 --- a/demos/demo-vue2/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ diff --git a/demos/demo-vue2/.eslintrc.js b/demos/demo-vue2/.eslintrc.js deleted file mode 100644 index 8ba1e90f..00000000 --- a/demos/demo-vue2/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - root: true, - - env: { - node: true, - }, - - extends: [ - 'plugin:vue/essential', - '@vue/standard', - ], - - parserOptions: { - parser: 'babel-eslint', - }, - - rules: { - 'comma-dangle': ['error', 'always-multiline'], - }, -} diff --git a/demos/demo-vue2/index.html b/demos/demo-vue2/index.html deleted file mode 100644 index 94f63b04..00000000 --- a/demos/demo-vue2/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - Vite App - - -
- - - diff --git a/demos/demo-vue2/package.json b/demos/demo-vue2/package.json deleted file mode 100644 index ed7f983a..00000000 --- a/demos/demo-vue2/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "demo", - "version": "2.0.0-beta.12", - "private": true, - "scripts": { - "dev": "vite", - "build": "vite build", - "lint": "eslint . --ext .js,.vue" - }, - "dependencies": { - "core-js": "^3.8.1", - "floating-vue": "^1.0.0-beta.15", - "screenfull": "^4.2.0", - "vue": "^2.6.10", - "vue-router": "^3.0.1" - }, - "devDependencies": { - "@vue/eslint-config-standard": "^6.0.0", - "eslint": "^7.16.0", - "faker": "^4.1.0", - "highlight.js": "^9.7.0", - "sass": "^1.18.0", - "vite": "^2.8.6", - "vite-plugin-vue2": "^1.9.3", - "vue-template-compiler": "^2.6.10" - }, - "postcss": { - "plugins": { - "autoprefixer": {} - } - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not ie <= 8" - ], - "root": true -} diff --git a/demos/demo-vue2/public/.nojekyll b/demos/demo-vue2/public/.nojekyll deleted file mode 100644 index e69de29b..00000000 diff --git a/demos/demo-vue2/public/logo.png b/demos/demo-vue2/public/logo.png deleted file mode 100644 index 60e17006..00000000 Binary files a/demos/demo-vue2/public/logo.png and /dev/null differ diff --git a/demos/demo-vue2/public/test.html b/demos/demo-vue2/public/test.html deleted file mode 100644 index dfb7fbc1..00000000 --- a/demos/demo-vue2/public/test.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - -
-

- -

-

- classes: - - - - -

- -

v-tooltip="message": {{ message }}

-

v-tooltip="{content: message, classes: classes}": {{ message }}

-
- - - - diff --git a/demos/demo-vue2/src/App.vue b/demos/demo-vue2/src/App.vue deleted file mode 100644 index 915b0008..00000000 --- a/demos/demo-vue2/src/App.vue +++ /dev/null @@ -1,316 +0,0 @@ - - - diff --git a/demos/demo-vue2/src/CodeSnippet.vue b/demos/demo-vue2/src/CodeSnippet.vue deleted file mode 100644 index f2a8eb9d..00000000 --- a/demos/demo-vue2/src/CodeSnippet.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - diff --git a/demos/demo-vue2/src/Collapse.vue b/demos/demo-vue2/src/Collapse.vue deleted file mode 100644 index a03c9cea..00000000 --- a/demos/demo-vue2/src/Collapse.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - - - diff --git a/demos/demo-vue2/src/ExampleComponent.vue b/demos/demo-vue2/src/ExampleComponent.vue deleted file mode 100644 index 57ebdea7..00000000 --- a/demos/demo-vue2/src/ExampleComponent.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - - - diff --git a/demos/demo-vue2/src/PageHome.vue b/demos/demo-vue2/src/PageHome.vue deleted file mode 100644 index f8718482..00000000 --- a/demos/demo-vue2/src/PageHome.vue +++ /dev/null @@ -1,775 +0,0 @@ - - - - - diff --git a/demos/demo-vue2/src/PageHoverDropdown.vue b/demos/demo-vue2/src/PageHoverDropdown.vue deleted file mode 100644 index 62721534..00000000 --- a/demos/demo-vue2/src/PageHoverDropdown.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - diff --git a/demos/demo-vue2/src/PageInstall.vue b/demos/demo-vue2/src/PageInstall.vue deleted file mode 100644 index 765c1210..00000000 --- a/demos/demo-vue2/src/PageInstall.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - diff --git a/demos/demo-vue2/src/PageTable.vue b/demos/demo-vue2/src/PageTable.vue deleted file mode 100644 index 358150f0..00000000 --- a/demos/demo-vue2/src/PageTable.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - - - diff --git a/demos/demo-vue2/src/main.js b/demos/demo-vue2/src/main.js deleted file mode 100644 index 6d97da9b..00000000 --- a/demos/demo-vue2/src/main.js +++ /dev/null @@ -1,70 +0,0 @@ -import Vue from 'vue' -import VueRouter from 'vue-router' -import FloatingVue, { createTooltip, destroyTooltip } from 'floating-vue' -import 'floating-vue/dist/style.css' -import App from './App.vue' -import PageHome from './PageHome.vue' -import PageInstall from './PageInstall.vue' - -Vue.use(FloatingVue, { - disposeTimeout: 5000, - themes: { - dropdown: { - popperOptions: { - modifiers: { - preventOverflow: { - padding: 12, - }, - }, - }, - }, - // Custom theme - 'info-tooltip': { - $extend: 'tooltip', - delay: { - show: 800, - hide: 500, - }, - }, - }, -}) - -FloatingVue.options.delay = { - show: 300, - hide: 0, -} - -console.log(FloatingVue.options) - -Vue.use(VueRouter) - -const router = new VueRouter({ - routes: [ - { path: '/', name: 'home', component: PageHome }, - { path: '/install', name: 'install', component: PageInstall }, - { path: '/table', name: 'table', component: () => import('./PageTable.vue') }, - { path: '/hover-dropdown', name: 'hover-dropdown', component: () => import('./PageHoverDropdown.vue') }, - { path: '*', redirect: '/' }, - ], -}) - -/* eslint-disable no-new */ -new Vue({ - el: '#app', - router, - render: h => h(App), -}) - -// Create tooltips without the directive -window.manualTooltip = () => { - const el = document.querySelector('button') - const tooltip = createTooltip(el, { - content: 'This is a manual tooltip', - placement: 'bottom', - triggers: [], - }) - tooltip.show() - setTimeout(() => { - destroyTooltip(el) - }, 2000) -} diff --git a/demos/demo-vue2/src/style/imports.scss b/demos/demo-vue2/src/style/imports.scss deleted file mode 100644 index a78d16fc..00000000 --- a/demos/demo-vue2/src/style/imports.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import './mixins'; -@import './vars'; -@import './md-colors'; diff --git a/demos/demo-vue2/src/style/md-colors.scss b/demos/demo-vue2/src/style/md-colors.scss deleted file mode 100644 index 2c7301cd..00000000 --- a/demos/demo-vue2/src/style/md-colors.scss +++ /dev/null @@ -1,294 +0,0 @@ -$md-red: #f44336; -$md-red-50: #ffebee; -$md-red-100: #ffcdd2; -$md-red-200: #ef9a9a; -$md-red-300: #e57373; -$md-red-400: #ef5350; -$md-red-500: #f44336; -$md-red-600: #e53935; -$md-red-700: #d32f2f; -$md-red-800: #c62828; -$md-red-900: #b71c1c; -$md-red-a100: #ff8a80; -$md-red-a200: #ff5252; -$md-red-a400: #ff1744; -$md-red-a700: #d50000; - -$md-pink: #e91e63; -$md-pink-50: #fce4ec; -$md-pink-100: #f8bbd0; -$md-pink-200: #f48fb1; -$md-pink-300: #f06292; -$md-pink-400: #ec407a; -$md-pink-500: #e91e63; -$md-pink-600: #d81b60; -$md-pink-700: #c2185b; -$md-pink-800: #ad1457; -$md-pink-900: #880e4f; -$md-pink-a100: #ff80ab; -$md-pink-a200: #ff4081; -$md-pink-a400: #f50057; -$md-pink-a700: #c51162; - -$md-purple: #9c27b0; -$md-purple-50: #f3e5f5; -$md-purple-100: #e1bee7; -$md-purple-200: #ce93d8; -$md-purple-300: #ba68c8; -$md-purple-400: #ab47bc; -$md-purple-500: #9c27b0; -$md-purple-600: #8e24aa; -$md-purple-700: #7b1fa2; -$md-purple-800: #6a1b9a; -$md-purple-900: #4a148c; -$md-purple-a100: #ea80fc; -$md-purple-a200: #e040fb; -$md-purple-a400: #d500f9; -$md-purple-a700: #aa00ff; - -$md-deep-purple: #673ab7; -$md-deep-purple-50: #ede7f6; -$md-deep-purple-100: #d1c4e9; -$md-deep-purple-200: #b39ddb; -$md-deep-purple-300: #9575cd; -$md-deep-purple-400: #7e57c2; -$md-deep-purple-500: #673ab7; -$md-deep-purple-600: #5e35b1; -$md-deep-purple-700: #512da8; -$md-deep-purple-800: #4527a0; -$md-deep-purple-900: #311b92; -$md-deep-purple-a100: #b388ff; -$md-deep-purple-a200: #7c4dff; -$md-deep-purple-a400: #651fff; -$md-deep-purple-a700: #6200ea; - -$md-indigo: #3f51b5; -$md-indigo-50: #e8eaf6; -$md-indigo-100: #c5cae9; -$md-indigo-200: #9fa8da; -$md-indigo-300: #7986cb; -$md-indigo-400: #5c6bc0; -$md-indigo-500: #3f51b5; -$md-indigo-600: #3949ab; -$md-indigo-700: #303f9f; -$md-indigo-800: #283593; -$md-indigo-900: #1a237e; -$md-indigo-a100: #8c9eff; -$md-indigo-a200: #536dfe; -$md-indigo-a400: #3d5afe; -$md-indigo-a700: #304ffe; - -$md-blue: #2196f3; -$md-blue-50: #e3f2fd; -$md-blue-100: #bbdefb; -$md-blue-200: #90caf9; -$md-blue-300: #64b5f6; -$md-blue-400: #42a5f5; -$md-blue-500: #2196f3; -$md-blue-600: #1e88e5; -$md-blue-700: #1976d2; -$md-blue-800: #1565c0; -$md-blue-900: #0d47a1; -$md-blue-a100: #82b1ff; -$md-blue-a200: #448aff; -$md-blue-a400: #2979ff; -$md-blue-a700: #2962ff; - -$md-light-blue: #03a9f4; -$md-light-blue-50: #e1f5fe; -$md-light-blue-100: #b3e5fc; -$md-light-blue-200: #81d4fa; -$md-light-blue-300: #4fc3f7; -$md-light-blue-400: #29b6f6; -$md-light-blue-500: #03a9f4; -$md-light-blue-600: #039be5; -$md-light-blue-700: #0288d1; -$md-light-blue-800: #0277bd; -$md-light-blue-900: #01579b; -$md-light-blue-a100: #80d8ff; -$md-light-blue-a200: #40c4ff; -$md-light-blue-a400: #00b0ff; -$md-light-blue-a700: #0091ea; - -$md-cyan: #00bcd4; -$md-cyan-50: #e0f7fa; -$md-cyan-100: #b2ebf2; -$md-cyan-200: #80deea; -$md-cyan-300: #4dd0e1; -$md-cyan-400: #26c6da; -$md-cyan-500: #00bcd4; -$md-cyan-600: #00acc1; -$md-cyan-700: #0097a7; -$md-cyan-800: #00838f; -$md-cyan-900: #006064; -$md-cyan-a100: #84ffff; -$md-cyan-a200: #18ffff; -$md-cyan-a400: #00e5ff; -$md-cyan-a700: #00b8d4; - -$md-teal: #009688; -$md-teal-50: #e0f2f1; -$md-teal-100: #b2dfdb; -$md-teal-200: #80cbc4; -$md-teal-300: #4db6ac; -$md-teal-400: #26a69a; -$md-teal-500: #009688; -$md-teal-600: #00897b; -$md-teal-700: #00796b; -$md-teal-800: #00695c; -$md-teal-900: #004d40; -$md-teal-a100: #a7ffeb; -$md-teal-a200: #64ffda; -$md-teal-a400: #1de9b6; -$md-teal-a700: #00bfa5; - -$md-green: #4caf50; -$md-green-50: #e8f5e9; -$md-green-100: #c8e6c9; -$md-green-200: #a5d6a7; -$md-green-300: #81c784; -$md-green-400: #66bb6a; -$md-green-500: #4caf50; -$md-green-600: #43a047; -$md-green-700: #388e3c; -$md-green-800: #2e7d32; -$md-green-900: #1b5e20; -$md-green-a100: #b9f6ca; -$md-green-a200: #69f0ae; -$md-green-a400: #00e676; -$md-green-a700: #00c853; - -$md-light-green: #8bc34a; -$md-light-green-50: #f1f8e9; -$md-light-green-100: #dcedc8; -$md-light-green-200: #c5e1a5; -$md-light-green-300: #aed581; -$md-light-green-400: #9ccc65; -$md-light-green-500: #8bc34a; -$md-light-green-600: #7cb342; -$md-light-green-700: #689f38; -$md-light-green-800: #558b2f; -$md-light-green-900: #33691e; -$md-light-green-a100: #ccff90; -$md-light-green-a200: #b2ff59; -$md-light-green-a400: #76ff03; -$md-light-green-a700: #64dd17; - -$md-lime: #cddc39; -$md-lime-50: #f9fbe7; -$md-lime-100: #f0f4c3; -$md-lime-200: #e6ee9c; -$md-lime-300: #dce775; -$md-lime-400: #d4e157; -$md-lime-500: #cddc39; -$md-lime-600: #c0ca33; -$md-lime-700: #afb42b; -$md-lime-800: #9e9d24; -$md-lime-900: #827717; -$md-lime-a100: #f4ff81; -$md-lime-a200: #eeff41; -$md-lime-a400: #c6ff00; -$md-lime-a700: #aeea00; - -$md-yellow: #ffeb3b; -$md-yellow-50: #fffde7; -$md-yellow-100: #fff9c4; -$md-yellow-200: #fff59d; -$md-yellow-300: #fff176; -$md-yellow-400: #ffee58; -$md-yellow-500: #ffeb3b; -$md-yellow-600: #fdd835; -$md-yellow-700: #fbc02d; -$md-yellow-800: #f9a825; -$md-yellow-900: #f57f17; -$md-yellow-a100: #ffff8d; -$md-yellow-a200: #ffff00; -$md-yellow-a400: #ffea00; -$md-yellow-a700: #ffd600; - -$md-amber: #ffc107; -$md-amber-50: #fff8e1; -$md-amber-100: #ffecb3; -$md-amber-200: #ffe082; -$md-amber-300: #ffd54f; -$md-amber-400: #ffca28; -$md-amber-500: #ffc107; -$md-amber-600: #ffb300; -$md-amber-700: #ffa000; -$md-amber-800: #ff8f00; -$md-amber-900: #ff6f00; -$md-amber-a100: #ffe57f; -$md-amber-a200: #ffd740; -$md-amber-a400: #ffc400; -$md-amber-a700: #ffab00; - -$md-orange: #ff9800; -$md-orange-50: #fff3e0; -$md-orange-100: #ffe0b2; -$md-orange-200: #ffcc80; -$md-orange-300: #ffb74d; -$md-orange-400: #ffa726; -$md-orange-500: #ff9800; -$md-orange-600: #fb8c00; -$md-orange-700: #f57c00; -$md-orange-800: #ef6c00; -$md-orange-900: #e65100; -$md-orange-a100: #ffd180; -$md-orange-a200: #ffab40; -$md-orange-a400: #ff9100; -$md-orange-a700: #ff6d00; - -$md-deep-orange: #ff5722; -$md-deep-orange-50: #fbe9e7; -$md-deep-orange-100: #ffccbc; -$md-deep-orange-200: #ffab91; -$md-deep-orange-300: #ff8a65; -$md-deep-orange-400: #ff7043; -$md-deep-orange-500: #ff5722; -$md-deep-orange-600: #f4511e; -$md-deep-orange-700: #e64a19; -$md-deep-orange-800: #d84315; -$md-deep-orange-900: #bf360c; -$md-deep-orange-a100: #ff9e80; -$md-deep-orange-a200: #ff6e40; -$md-deep-orange-a400: #ff3d00; -$md-deep-orange-a700: #dd2c00; - -$md-brown: #795548; -$md-brown-50: #efebe9; -$md-brown-100: #d7ccc8; -$md-brown-200: #bcaaa4; -$md-brown-300: #a1887f; -$md-brown-400: #8d6e63; -$md-brown-500: #795548; -$md-brown-600: #6d4c41; -$md-brown-700: #5d4037; -$md-brown-800: #4e342e; -$md-brown-900: #3e2723; - -$md-grey: #9e9e9e; -$md-grey-50: #fafafa; -$md-grey-100: #f5f5f5; -$md-grey-200: #eeeeee; -$md-grey-300: #e0e0e0; -$md-grey-400: #bdbdbd; -$md-grey-500: #9e9e9e; -$md-grey-600: #757575; -$md-grey-700: #616161; -$md-grey-800: #424242; -$md-grey-900: #212121; - -$md-blue-grey: #607d8b; -$md-blue-grey-50: #eceff1; -$md-blue-grey-100: #cfd8dc; -$md-blue-grey-200: #b0bec5; -$md-blue-grey-300: #90a4ae; -$md-blue-grey-400: #78909c; -$md-blue-grey-500: #607d8b; -$md-blue-grey-600: #546e7a; -$md-blue-grey-700: #455a64; -$md-blue-grey-800: #37474f; -$md-blue-grey-900: #263238; - -$md-black: #000000; -$md-white: #ffffff; diff --git a/demos/demo-vue2/src/style/mixins.scss b/demos/demo-vue2/src/style/mixins.scss deleted file mode 100644 index 12fed8f8..00000000 --- a/demos/demo-vue2/src/style/mixins.scss +++ /dev/null @@ -1,79 +0,0 @@ -@mixin ellipsis { - overflow: hidden; - -ms-text-overflow: ellipsis; - text-overflow: ellipsis; - white-space: nowrap; -} - -@mixin bounds($distance) { - top: $distance; - bottom: $distance; - right: $distance; - left: $distance; -} - -@mixin overlay { - position: absolute; - @include bounds(0); -} - -@mixin flex-box { - display: flex; - - & > * { - flex: auto 0 0; - } -} - -@mixin h-box { - @include flex-box; - flex-direction: row; -} - -@mixin v-box { - @include flex-box; - flex-direction: column; -} - -@mixin flex-control { - width: 0 !important; -} - -@mixin box-center { - align-items: center; - justify-content: center; -} - -@mixin toolbar-btn ($bg) { - background: fade($bg, 80%); - color: black; - transition: background 0.2s; - - &:hover { - color: black; - background: $bg; - } -} - -@mixin space-between-x($margin) { - margin-right: $margin; - - &:last-child { - margin-right: 0; - } -} - -@mixin space-between-y($margin) { - margin-bottom: $margin; - - &:last-child { - margin-bottom: 0; - } -} - -@mixin unselectable { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} diff --git a/demos/demo-vue2/src/style/vars.scss b/demos/demo-vue2/src/style/vars.scss deleted file mode 100644 index cde888ab..00000000 --- a/demos/demo-vue2/src/style/vars.scss +++ /dev/null @@ -1 +0,0 @@ -$primary-color: #40b883; diff --git a/demos/demo-vue2/vite.config.ts b/demos/demo-vue2/vite.config.ts deleted file mode 100644 index 3fcefab8..00000000 --- a/demos/demo-vue2/vite.config.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { defineConfig } from 'vite' -import { createVuePlugin } from 'vite-plugin-vue2' -import path from 'path' - -export default defineConfig({ - plugins: [ - createVuePlugin({ - vueTemplateOptions: { - compilerOptions: { - whitespace: 'preserve', - }, - }, - }), - ], - - css: { - preprocessorOptions: { - scss: { - additionalData: '@import "@/style/imports.scss";', - }, - }, - }, - - resolve: { - alias: [ - { find: '@', replacement: path.resolve(__dirname, 'src') } - ], - }, -}) diff --git a/docs/.vitepress/components/DropdownCloseDirectiveDemo.vue b/docs/.vitepress/components/DropdownCloseDirectiveDemo.vue new file mode 100644 index 00000000..2a38717e --- /dev/null +++ b/docs/.vitepress/components/DropdownCloseDirectiveDemo.vue @@ -0,0 +1,16 @@ + diff --git a/docs/.vitepress/components/DropdownSimpleExample.vue b/docs/.vitepress/components/DropdownSimpleExample.vue index 66441e22..7a20490e 100644 --- a/docs/.vitepress/components/DropdownSimpleExample.vue +++ b/docs/.vitepress/components/DropdownSimpleExample.vue @@ -1,3 +1,9 @@ + + - - diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 71737b32..8421ce8a 100755 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -113,5 +113,11 @@ export default defineConfig({ }, ], }, + search: { + provider: 'local', + options: { + detailedView: true, + }, + }, }, }) diff --git a/docs/.vitepress/theme/global.d.ts b/docs/.vitepress/theme/global.d.ts new file mode 100644 index 00000000..02c447ba --- /dev/null +++ b/docs/.vitepress/theme/global.d.ts @@ -0,0 +1,9 @@ +import { Dropdown, Tooltip, Menu } from 'floating-vue' + +declare module 'vue' { + export interface GlobalComponents { + VDropdown: typeof Dropdown + VTooltip: typeof Tooltip + VMenu: typeof Menu + } +} diff --git a/docs/.vitepress/theme/style.postcss b/docs/.vitepress/theme/style.postcss index 512c1e9c..0261ebb5 100644 --- a/docs/.vitepress/theme/style.postcss +++ b/docs/.vitepress/theme/style.postcss @@ -4,6 +4,10 @@ :root { --vp-z-index-nav: 10500; + --vp-c-brand-1: #41b88f; + --vp-c-brand-2: #2ab289; + --vp-c-brand-3: #1b9371; + --vp-c-brand-soft: rgba(65, 184, 143, 0.16); } .example { @@ -23,6 +27,9 @@ @apply p-2; } +.VPLocalSearchBox { + z-index: 10600 !important; +} /* Fix base styles for Tailwind (vitepress) */ diff --git a/docs/api/index.md b/docs/api/index.md index 2d48cfab..ee11bddf 100755 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -16,6 +16,18 @@ import { hideAllPoppers } from 'floating-vue' hideAllPoppers() ``` +### `recomputeAllPoppers` + +Recompute the position of all shown poppers. + +```js +import { recomputeAllPoppers } from 'floating-vue' + +recomputeAllPoppers() +``` + +This function is automatically called when the window is resized. + ### `createTooltip` `createTooltip(el, valueOrOptions, directiveModifiers)` creates a tooltip on a given element. @@ -537,10 +549,6 @@ When the popper is going to be hidden. Emitted after the hide delay. -### `dispose` - -Popper instance is destroyed. - ### `auto-hide` Emitted when the popper is closed if clicked outside. diff --git a/docs/components.d.ts b/docs/components.d.ts index 1ee664e8..16676c7e 100644 --- a/docs/components.d.ts +++ b/docs/components.d.ts @@ -8,9 +8,11 @@ export {} declare module 'vue' { export interface GlobalComponents { ArrowPadding: typeof import('./.vitepress/components/ArrowPadding.vue')['default'] + DropdownCloseDirectiveDemo: typeof import('./.vitepress/components/DropdownCloseDirectiveDemo.vue')['default'] DropdownMobileDemo: typeof import('./.vitepress/components/DropdownMobileDemo.vue')['default'] DropdownPlacement: typeof import('./.vitepress/components/DropdownPlacement.vue')['default'] DropdownSimpleExample: typeof import('./.vitepress/components/DropdownSimpleExample.vue')['default'] + DropdownVClodePopperDemo: typeof import('./.vitepress/components/DropdownVClodePopperDemo.vue')['default'] MenuSimpleExample: typeof import('./.vitepress/components/MenuSimpleExample.vue')['default'] OffsetExample: typeof import('./.vitepress/components/OffsetExample.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/docs/guide/component.md b/docs/guide/component.md index dbce4e7e..d3272db2 100644 --- a/docs/guide/component.md +++ b/docs/guide/component.md @@ -218,7 +218,7 @@ Use the `hide` slot prop to close the popper: ``` @@ -232,24 +232,26 @@ Use the `v-close-popper` directive on an element inside the dropdown to close it ``` + + The directive works even in nested components in the `popper` slot. You can also set it to true or false to enable or disable the directive (enabled by default): ```html -Close -Close + + ``` You can also use a property: ```html -Close + ``` ```js diff --git a/docs/guide/config.md b/docs/guide/config.md index 51ea7362..4e843589 100644 --- a/docs/guide/config.md +++ b/docs/guide/config.md @@ -62,6 +62,10 @@ export const config: FloatingVueConfig = { arrowPadding: 0, // Compute arrow overflow (useful to hide it) arrowOverflow: true, + /** + * By default, compute autohide on 'click'. + */ + autoHideOnMousedown: false, // Themes themes: { tooltip: { diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 53e861be..10fe0a0d 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -4,7 +4,7 @@ | floating-vue | NPM Tag | Vue compatibility | | ------------ | ------- | ----------------- | -| 2.x | latest | 3.x | +| 5.x | latest | 3.x | | 1.x | vue2 | 2.x | ## Node @@ -38,16 +38,16 @@ Or use the directives and components directly: ```javascript import { // Directives - VTooltip, - VClosePopper, + vTooltip, + vClosePopper, // Components Dropdown, Tooltip, Menu } from 'floating-vue' -app.directive('tooltip', VTooltip) -app.directive('close-popper', VClosePopper) +app.directive('tooltip', vTooltip) +app.directive('close-popper', vClosePopper) app.component('VDropdown', Dropdown) app.component('VTooltip', Tooltip) @@ -84,17 +84,53 @@ Or use the directives and components directly: ```javascript // Directives -app.directive('tooltip', FloatingVue.VTooltip) -app.directive('close-popper', FloatingVue.VClosePopper) +app.directive('tooltip', FloatingVue.vTooltip) +app.directive('close-popper', FloatingVue.vClosePopper) // Components app.component('VDropdown', FloatingVue.Dropdown) app.component('VTooltip', FloatingVue.Tooltip) app.component('VMenu', FloatingVue.Menu) ``` +## Import directly + +If you don't want to install the plugin into your Vue app globally, you can import the directives and components directly: + +```vue + + + +``` + +You can change the configuration too: + +```js +import { options } from 'floating-vue' + +options.themes.myTheme = { + // ... +} +``` + ## Vue 2 -floating-vue v2 is compatible with Vue 3. For Vue 2, use floating-vue v1 instead: +floating-vue v5 is compatible with Vue 3. For Vue 2, use floating-vue v1 instead: ::: code-group @@ -128,16 +164,16 @@ Or use the directives and components directly: import Vue from 'vue' import { // Directives - VTooltip, - VClosePopper, + vTooltip, + vClosePopper, // Components Dropdown, Tooltip, Menu } from 'floating-vue' -Vue.directive('tooltip', VTooltip) -Vue.directive('close-popper', VClosePopper) +Vue.directive('tooltip', vTooltip) +Vue.directive('close-popper', vClosePopper) Vue.component('VDropdown', Dropdown) Vue.component('VTooltip', Tooltip) diff --git a/docs/migration/migration-from-v2.md b/docs/migration/migration-from-v2.md index f1b9508f..3bf9977c 100644 --- a/docs/migration/migration-from-v2.md +++ b/docs/migration/migration-from-v2.md @@ -21,7 +21,7 @@ floating-vue is a complete rewrite compared to v-tooltip. This migration guide w ### Floating UI -The positionning library has changed from `popperjs` to [`floating-ui`](https://floating-ui.com/) which is the spiritual successor. +The positioning library has changed from `popperjs` to [`floating-ui`](https://floating-ui.com/) which is the spiritual successor. ### Global configuration diff --git a/docs/package.json b/docs/package.json index 534becda..e8fabf93 100755 --- a/docs/package.json +++ b/docs/package.json @@ -4,6 +4,7 @@ "description": "floating-vue docs", "private": true, "main": "index.js", + "type": "module", "authors": { "name": "Guillaume Chau", "email": "guillaume.b.chau@gmail.com" @@ -38,7 +39,7 @@ "unplugin-icons": "^0.16.3", "unplugin-vue-components": "^0.25.1", "vite": "^4.3.9", - "vitepress": "1.0.0-beta.2", + "vitepress": "^1.0.0-rc.36", "vue": "^3.3.4" } } diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 00000000..f8c2e99b --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,11 @@ +{ + "include": [ + ".vitepress/**/*.ts", + ".vitepress/**/*.vue" + ], + "exclude": [ + "node_modules", + "dist", + "**/*.js" + ] +} diff --git a/package.json b/package.json index 9b5b9965..2aab86bb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "floating-vue-monorepo", "packageManager": "pnpm@8.6.2", - "version": "2.0.0-reedsy.1.0.2", + "version": "5.2.2-reedsy.1.0.2", "private": true, "scripts": { "build": "pnpm -r --filter=\"./packages/*\" run build", diff --git a/packages/floating-vue/nuxt.mjs b/packages/floating-vue/nuxt.mjs index 64f6b45b..f30fb24c 100644 --- a/packages/floating-vue/nuxt.mjs +++ b/packages/floating-vue/nuxt.mjs @@ -8,7 +8,7 @@ export default async function (_, _nuxt) { addPluginTemplate({ filename: 'floating-vue.mjs', getContents: () => ` - import { defineNuxtPlugin } from '#app' + import { defineNuxtPlugin } from '#imports' import FloatingVue from 'floating-vue' export default defineNuxtPlugin((nuxtApp) => { diff --git a/packages/floating-vue/package.json b/packages/floating-vue/package.json index ee04f2f4..723c7640 100644 --- a/packages/floating-vue/package.json +++ b/packages/floating-vue/package.json @@ -1,6 +1,6 @@ { "name": "@reedsy/floating-vue", - "version": "2.0.0-reedsy.1.0.2", + "version": "5.2.2-reedsy.1.0.2", "description": "Easy Vue tooltips, dropdowns, menus & popovers using floating-ui", "author": "Guillaume Chau ", "scripts": { diff --git a/packages/floating-vue/src/components/Dropdown.ts b/packages/floating-vue/src/components/Dropdown.ts new file mode 100644 index 00000000..b8b10674 --- /dev/null +++ b/packages/floating-vue/src/components/Dropdown.ts @@ -0,0 +1,9 @@ +import PopperWrapper from './PopperWrapper.vue' + +const Component = ({ + ...PopperWrapper, + name: 'VDropdown', + vPopperTheme: 'dropdown', +}) as unknown as typeof PopperWrapper + +export default Component diff --git a/packages/floating-vue/src/components/Dropdown.vue b/packages/floating-vue/src/components/Dropdown.vue deleted file mode 100644 index 559c36ee..00000000 --- a/packages/floating-vue/src/components/Dropdown.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/packages/floating-vue/src/components/Menu.vue b/packages/floating-vue/src/components/Menu.ts similarity index 87% rename from packages/floating-vue/src/components/Menu.vue rename to packages/floating-vue/src/components/Menu.ts index 2ec8a5c3..bcbfb336 100644 --- a/packages/floating-vue/src/components/Menu.vue +++ b/packages/floating-vue/src/components/Menu.ts @@ -1,4 +1,3 @@ - diff --git a/packages/floating-vue/src/components/Popper.ts b/packages/floating-vue/src/components/Popper.ts index c7ea7d31..3a4febae 100644 --- a/packages/floating-vue/src/components/Popper.ts +++ b/packages/floating-vue/src/components/Popper.ts @@ -14,14 +14,20 @@ import { placements, Placement } from '../util/popper' import { SHOW_EVENT_MAP, HIDE_EVENT_MAP } from '../util/events' import { removeFromArray } from '../util/lang' import { nextFrame } from '../util/frame' -import { getDefaultConfig, getAllParentThemes } from '../config' +import { getDefaultConfig, getAllParentThemes, config } from '../config' export type ComputePositionConfig = Parameters[2] -const shownPoppers = [] +interface PopperEvent extends Event { + usedByTooltip?: boolean + closeAllPopover?: boolean + closePopover?: boolean +} + +const shownPoppers: PopperInstance[] = [] let hidingPopper = null -const shownPoppersByTheme: Record = {} +const shownPoppersByTheme: Record = {} function getShownPoppersByTheme (theme: string) { let list = shownPoppersByTheme[theme] if (!list) { @@ -43,7 +49,7 @@ function defaultPropFactory (prop: string) { const PROVIDE_KEY = '__floating-vue__popper' -export default () => defineComponent({ +const createPopper = () => defineComponent({ name: 'VPopper', provide () { @@ -273,18 +279,17 @@ export default () => defineComponent({ }, }, - emits: [ - 'show', - 'hide', - 'update:shown', - 'apply-show', - 'apply-hide', - 'close-group', - 'close-directive', - 'auto-hide', - 'resize', - 'dispose', - ], + emits: { + show: () => true, + hide: () => true, + 'update:shown': (shown: boolean) => true, + 'apply-show': () => true, + 'apply-hide': () => true, + 'close-group': () => true, + 'close-directive': () => true, + 'auto-hide': () => true, + resize: () => true, + }, data () { return { @@ -309,8 +314,13 @@ export default () => defineComponent({ }, transformOrigin: null, }, + randomId: `popper_${[Math.random(), Date.now()].map(n => n.toString(36).substring(2, 10)).join('_')}`, shownChildren: new Set(), lastAutoHide: true, + pendingHide: false, + containsGlobalTarget: false, + isDisposed: true, + mouseDownContains: false, } }, @@ -370,13 +380,12 @@ export default () => defineComponent({ } }, - ...[ - 'triggers', - 'positioningDisabled', - ].reduce((acc, prop) => { - acc[prop] = '$_refreshListeners' - return acc - }, {}), + triggers: { + handler: '$_refreshListeners', + deep: true, + }, + + positioningDisabled: '$_refreshListeners', ...[ 'placement', @@ -397,8 +406,6 @@ export default () => defineComponent({ }, created () { - this.$_isDisposed = true - this.randomId = `popper_${[Math.random(), Date.now()].map(n => n.toString(36).substring(2, 10)).join('_')}` if (this.autoMinSize) { console.warn('[floating-vue] `autoMinSize` option is deprecated. Use `autoSize="min"` instead.') } @@ -428,7 +435,7 @@ export default () => defineComponent({ show ({ event = null, skipDelay = false, force = false } = {}) { if (this.parentPopper?.lockedChild && this.parentPopper.lockedChild !== this) return - this.$_pendingHide = false + this.pendingHide = false if (force || !this.disabled) { if (this.parentPopper?.lockedChild === this) { this.parentPopper.lockedChild = null @@ -451,7 +458,7 @@ export default () => defineComponent({ // Abort if child is shown if (new Set(this.shownChildren).size > 0) { - this.$_pendingHide = true + this.pendingHide = true return } @@ -473,7 +480,7 @@ export default () => defineComponent({ this.parentPopper.lockedChild = null } - this.$_pendingHide = false + this.pendingHide = false this.$_scheduleHide(event, skipDelay) this.$emit('hide') @@ -481,8 +488,8 @@ export default () => defineComponent({ }, init () { - if (!this.$_isDisposed) return - this.$_isDisposed = false + if (!this.isDisposed) return + this.isDisposed = false this.isMounted = false this.$_events = [] this.$_preventShow = false @@ -508,8 +515,8 @@ export default () => defineComponent({ }, dispose () { - if (this.$_isDisposed) return - this.$_isDisposed = true + if (this.isDisposed) return + this.isDisposed = true this.$_removeEventListeners() this.hide({ skipDelay: true }) this.$_detachPopperNode() @@ -520,8 +527,6 @@ export default () => defineComponent({ this.$_updateParentShownChildren(false) this.$_swapTargetAttrs('data-original-title', 'title') - - this.$emit('dispose') }, async onResize () { @@ -532,7 +537,7 @@ export default () => defineComponent({ }, async $_computePosition () { - if (this.$_isDisposed || this.positioningDisabled) return + if (this.isDisposed || this.positioningDisabled) return const options: ComputePositionConfig = { strategy: this.strategy, @@ -665,7 +670,7 @@ export default () => defineComponent({ }) }, - $_scheduleShow (event = null, skipDelay = false) { + $_scheduleShow (_event, skipDelay = false) { this.$_updateParentShownChildren(true) this.$_hideInProgress = false clearTimeout(this.$_scheduleTimer) @@ -683,9 +688,9 @@ export default () => defineComponent({ } }, - $_scheduleHide (event = null, skipDelay = false) { + $_scheduleHide (_event, skipDelay = false) { if (new Set(this.shownChildren).size > 0) { - this.$_pendingHide = true + this.pendingHide = true return } this.$_updateParentShownChildren(false) @@ -704,7 +709,7 @@ export default () => defineComponent({ } }, - $_computeDelay (type) { + $_computeDelay (type: 'show' | 'hide') { const delay = this.delay return parseInt((delay && delay[type]) || delay || 0) }, @@ -789,7 +794,7 @@ export default () => defineComponent({ async $_applyHide (skipTransition = false) { if (new Set(this.shownChildren).size > 0) { - this.$_pendingHide = true + this.pendingHide = true this.$_hideInProgress = false return } @@ -859,7 +864,7 @@ export default () => defineComponent({ }, $_ensureTeleport () { - if (this.$_isDisposed) return + if (this.isDisposed) return let container = this.container // if container is a query, get the relative element @@ -881,7 +886,7 @@ export default () => defineComponent({ $_addEventListeners () { // Add trigger show events - const handleShow = event => { + const handleShow = (event: PopperEvent) => { if (this.isShown && !this.$_hideInProgress) { return } @@ -895,7 +900,7 @@ export default () => defineComponent({ // Add trigger hide events - const handleHide = event => { + const handleHide = (event: PopperEvent) => { if (event.usedByTooltip) { return } @@ -906,7 +911,7 @@ export default () => defineComponent({ this.$_registerTriggerListeners([this.$_popperNode], HIDE_EVENT_MAP, this.popperTriggers, this.popperHideTriggers, handleHide) }, - $_registerEventListeners (targetNodes: any[], eventType: string, handler: (event: Event) => void) { + $_registerEventListeners (targetNodes: Element[], eventType: string, handler: (event: Event) => void) { this.$_events.push({ targetNodes, eventType, handler }) targetNodes.forEach(node => node.addEventListener(eventType, handler, supportsPassive ? { @@ -915,7 +920,7 @@ export default () => defineComponent({ : undefined)) }, - $_registerTriggerListeners (targetNodes: any[], eventMap: Record, commonTriggers, customTrigger, handler: (event: Event) => void) { + $_registerTriggerListeners (targetNodes: Element[], eventMap: Record, commonTriggers, customTrigger, handler: (event: Event) => void) { let triggers = commonTriggers if (customTrigger != null) { @@ -944,7 +949,7 @@ export default () => defineComponent({ }, $_refreshListeners () { - if (!this.$_isDisposed) { + if (!this.isDisposed) { this.$_removeEventListeners() this.$_addEventListeners() } @@ -1004,7 +1009,7 @@ export default () => defineComponent({ } else { parent.shownChildren.delete(this.randomId) - if (parent.$_pendingHide) { + if (parent.pendingHide) { parent.hide() } } @@ -1042,57 +1047,55 @@ export default () => defineComponent({ if (typeof document !== 'undefined' && typeof window !== 'undefined') { if (isIOS) { - document.addEventListener('touchstart', handleGlobalMousedown, supportsPassive - ? { - passive: true, - capture: true, - } - : true) - document.addEventListener('touchend', handleGlobalTouchend, supportsPassive + const options = supportsPassive ? { passive: true, capture: true, } - : true) + : true + document.addEventListener('touchstart', (event) => handleGlobalPointerDown(event, true), options) + document.addEventListener('touchend', (event) => handleGlobalPointerUp(event, true), options) } else { - window.addEventListener('mousedown', handleGlobalMousedown, true) - window.addEventListener('click', handleGlobalClick, true) + window.addEventListener('mousedown', (event) => handleGlobalPointerDown(event, false), true) + window.addEventListener('click', (event) => handleGlobalPointerUp(event, false), true) } - window.addEventListener('resize', computePositionAllShownPoppers) + window.addEventListener('resize', recomputeAllPoppers) } -function handleGlobalMousedown (event) { - for (let i = 0; i < shownPoppers.length; i++) { - const popper = shownPoppers[i] - try { - const popperContent = popper.popperNode() - popper.$_mouseDownContains = popperContent.contains(event.target) - } catch (e) { - // noop +function handleGlobalPointerDown (event: PopperEvent, touch: boolean) { + if (config.autoHideOnMousedown) { + handleGlobalClose(event, touch) + } else { + // Compute contains only + for (let i = 0; i < shownPoppers.length; i++) { + const popper = shownPoppers[i] + try { + popper.mouseDownContains = popper.popperNode().contains(event.target) + } catch (e) { + // noop + } } } } -function handleGlobalClick (event) { - handleGlobalClose(event) -} - -function handleGlobalTouchend (event) { - handleGlobalClose(event, true) +function handleGlobalPointerUp (event: PopperEvent, touch: boolean) { + if (!config.autoHideOnMousedown) { + handleGlobalClose(event, touch) + } } -function handleGlobalClose (event, touch = false) { +function handleGlobalClose (event: PopperEvent, touch: boolean) { const preventClose: Record = {} for (let i = shownPoppers.length - 1; i >= 0; i--) { const popper = shownPoppers[i] try { - const contains = popper.$_containsGlobalTarget = isContainingEventTarget(popper, event) - popper.$_pendingHide = false + const contains = popper.containsGlobalTarget = popper.mouseDownContains || popper.popperNode().contains(event.target) + popper.pendingHide = false // Delay so that close directive has time to set values (closeAllPopover, closePopover) requestAnimationFrame(() => { - popper.$_pendingHide = false + popper.pendingHide = false if (preventClose[popper.randomId]) return if (shouldAutoHide(popper, contains, event)) { @@ -1109,9 +1112,9 @@ function handleGlobalClose (event, touch = false) { } // Auto hide parents - let parent = popper.parentPopper + let parent = popper.parentPopper as PopperInstance while (parent) { - if (shouldAutoHide(parent, parent.$_containsGlobalTarget, event)) { + if (shouldAutoHide(parent, parent.containsGlobalTarget, event)) { parent.$_handleGlobalClose(event, touch) } else { break @@ -1126,16 +1129,11 @@ function handleGlobalClose (event, touch = false) { } } -function isContainingEventTarget (popper, event): boolean { - const popperContent = popper.popperNode() - return popper.$_mouseDownContains || popperContent.contains(event.target) -} - -function shouldAutoHide (popper, contains, event): boolean { +function shouldAutoHide (popper: PopperInstance, contains, event: PopperEvent): boolean { return event.closeAllPopover || (event.closePopover && contains) || (getAutoHideResult(popper, event) && !contains) } -function getAutoHideResult (popper, event) { +function getAutoHideResult (popper: PopperInstance, event: Event) { if (typeof popper.autoHide === 'function') { const result = popper.autoHide(event) popper.lastAutoHide = result @@ -1144,10 +1142,10 @@ function getAutoHideResult (popper, event) { return popper.autoHide } -function computePositionAllShownPoppers (event) { +export function recomputeAllPoppers () { for (let i = 0; i < shownPoppers.length; i++) { const popper = shownPoppers[i] - popper.$_computePosition(event) + popper.$_computePosition() } } @@ -1183,3 +1181,7 @@ function lineIntersectsLine (x1: number, y1: number, x2: number, y2: number, x3: const uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)) return (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) } + +export default createPopper + +export type PopperInstance = ReturnType extends { new (): infer T } ? T : never diff --git a/packages/floating-vue/src/components/PopperContent.vue b/packages/floating-vue/src/components/PopperContent.vue index 1b09e552..b3bce00b 100644 --- a/packages/floating-vue/src/components/PopperContent.vue +++ b/packages/floating-vue/src/components/PopperContent.vue @@ -111,166 +111,3 @@ export default defineComponent({ }, }) - - diff --git a/packages/floating-vue/src/components/PopperWrapper.vue b/packages/floating-vue/src/components/PopperWrapper.vue index 31fc5bde..ba1a1b64 100644 --- a/packages/floating-vue/src/components/PopperWrapper.vue +++ b/packages/floating-vue/src/components/PopperWrapper.vue @@ -14,12 +14,22 @@ classes, result, }" + v-bind="$props" :theme="finalTheme" :target-nodes="getTargetNodes" :popper-node="() => ($refs as any).popperContent.$el" :class="[ themeClass, ]" + @show="() => $emit('show')" + @hide="() => $emit('hide')" + @update:shown="(shown) => $emit('update:shown', shown)" + @apply-show="() => $emit('apply-show')" + @apply-hide="() => $emit('apply-hide')" + @close-group="() => $emit('close-group')" + @close-directive="() => $emit('close-directive')" + @auto-hide="() => $emit('auto-hide')" + @resize="() => $emit('resize')" > - - diff --git a/packages/floating-vue/src/config.ts b/packages/floating-vue/src/config.ts index 2bed497d..30a3ffa7 100644 --- a/packages/floating-vue/src/config.ts +++ b/packages/floating-vue/src/config.ts @@ -14,7 +14,7 @@ export const config: FloatingVueConfig = { // Skip delay & CSS transitions when another popper is shown, so that the popper appear to instanly move to the new position. instantMove: false, // Auto destroy tooltip DOM nodes (ms) - disposeTimeout: 5000, + disposeTimeout: 150, // Triggers on the popper itself popperTriggers: [], // Positioning strategy @@ -31,6 +31,10 @@ export const config: FloatingVueConfig = { arrowPadding: 0, // Compute arrow overflow (useful to hide it) arrowOverflow: true, + /** + * By default, compute autohide on 'click'. + */ + autoHideOnMousedown: false, // Themes themes: { tooltip: { @@ -67,7 +71,7 @@ export const config: FloatingVueConfig = { menu: { $extend: 'dropdown', triggers: ['hover', 'focus'], - popperTriggers: ['hover', 'focus'], + popperTriggers: ['hover'], delay: { show: 0, hide: 400, diff --git a/packages/floating-vue/src/directives/v-close-popper.ts b/packages/floating-vue/src/directives/v-close-popper.ts index 676182f8..bdd2ff9f 100644 --- a/packages/floating-vue/src/directives/v-close-popper.ts +++ b/packages/floating-vue/src/directives/v-close-popper.ts @@ -1,7 +1,8 @@ import { supportsPassive } from '../util/env' function addListeners (el) { - el.addEventListener('click', onClick) + el.addEventListener('mousedown', addEventProps) + el.addEventListener('click', addEventProps) el.addEventListener('touchstart', onTouchStart, supportsPassive ? { passive: true, @@ -10,13 +11,14 @@ function addListeners (el) { } function removeListeners (el) { - el.removeEventListener('click', onClick) + el.removeEventListener('mousedown', addEventProps) + el.removeEventListener('click', addEventProps) el.removeEventListener('touchstart', onTouchStart) el.removeEventListener('touchend', onTouchEnd) el.removeEventListener('touchcancel', onTouchCancel) } -function onClick (event) { +function addEventProps (event) { const el = event.currentTarget event.closePopover = !el.$_vclosepopover_touch event.closeAllPopover = el.$_closePopoverModifiers && !!el.$_closePopoverModifiers.all diff --git a/packages/floating-vue/src/index.ts b/packages/floating-vue/src/index.ts index 42ca343c..c9f7fd46 100644 --- a/packages/floating-vue/src/index.ts +++ b/packages/floating-vue/src/index.ts @@ -1,15 +1,16 @@ import { assign } from './util/assign-deep' import { config, FloatingVueConfig } from './config' import 'vue-resize/dist/vue-resize.css' +import './style.css' // Components -import PrivateDropdown from './components/Dropdown.vue' -import PrivateMenu from './components/Menu.vue' +import PrivateDropdown from './components/Dropdown' +import PrivateMenu from './components/Menu' import PrivatePopper from './components/Popper' import PrivatePopperContent from './components/PopperContent.vue' import PrivatePopperMethods from './components/PopperMethods' import PrivatePopperWrapper from './components/PopperWrapper.vue' import PrivateThemeClass from './components/ThemeClass' -import PrivateTooltip from './components/Tooltip.vue' +import PrivateTooltip from './components/Tooltip' import PrivateTooltipDirective from './components/TooltipDirective.vue' // Directives import PrivateVTooltip from './directives/v-tooltip' @@ -19,9 +20,17 @@ import PrivateVClosePopper from './directives/v-close-popper' export const options = config // Directive +/** + * @deprecated Import `vTooltip` instead. + */ export const VTooltip = PrivateVTooltip +export const vTooltip = PrivateVTooltip // For