From 1cc52e9acae41719b2d92d7bb2c5aa2e7e68d180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Ledentu?= Date: Fri, 5 Jul 2024 18:49:06 +0200 Subject: [PATCH] feat!: replace components by scoped slots for customization BREAKING CHANGE: previous custom components have been removed --- .eslintrc.js | 8 - .storybook/main.js | 5 +- babel.config.js | 2 +- docgen.config.js | 3 - docs/.vuepress/components/FinderExample.vue | 43 +--- docs/customization.md | 79 ++---- package.json | 4 - src/components/Finder.vue | 127 +++------- src/components/FinderItem.vue | 47 ++-- src/components/FinderList.vue | 104 +++++--- src/components/FinderListDropZone.vue | 10 +- src/components/__tests__/Finder.test.js | 12 +- src/components/__tests__/FinderItem.test.js | 29 +-- src/components/__tests__/FinderList.test.js | 13 +- .../__snapshots__/Finder.test.js.snap | 236 +++++++++--------- .../__snapshots__/FinderItem.test.js.snap | 12 +- .../__snapshots__/FinderList.test.js.snap | 169 +++++++------ .../FinderListDropZone.test.js.snap | 10 +- stories/index.stories.js | 65 ++--- vite.config.js | 3 +- 20 files changed, 457 insertions(+), 524 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b8de9dc..e05a4bd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,15 +5,7 @@ module.exports = { root: true, parserOptions: { parser: "@babel/eslint-parser", - babelOptions: { - parserOpts: { - plugins: ["jsx"], - }, - }, ecmaVersion: 2017, - ecmaFeatures: { - jsx: true, - }, sourceType: "module", }, plugins: ["html", "vue"], diff --git a/.storybook/main.js b/.storybook/main.js index 5c87bbd..c2b9344 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,6 +1,5 @@ const path = require("path"); -const { loadConfigFromFile, mergeConfig } = require("vite"); -const vueJsx = require("@vitejs/plugin-vue-jsx"); +const { loadConfigFromFile } = require("vite"); module.exports = { stories: [ @@ -32,7 +31,7 @@ module.exports = { "@": path.resolve("src"), }, }, - plugins: [...config.plugins, vueJsx()], + plugins: [...config.plugins], }; }, diff --git a/babel.config.js b/babel.config.js index 5b4c755..7aebebc 100644 --- a/babel.config.js +++ b/babel.config.js @@ -12,7 +12,7 @@ module.exports = { }, ], ], - plugins: ["transform-es2015-modules-commonjs", "@vue/babel-plugin-jsx"], + plugins: ["transform-es2015-modules-commonjs"], }, }, }; diff --git a/docgen.config.js b/docgen.config.js index ec50327..e18254a 100644 --- a/docgen.config.js +++ b/docgen.config.js @@ -7,9 +7,6 @@ module.exports = { componentsRoot: "src/components", //getDestFile: (file: string, config: DocgenCLIConfig) => path.join(config.outDir, file).replace(/\.vue$/ ".doc.md"), components: "**/Finder.vue", // the glob to define what files should be documented as components (relative to componentRoot) - apiOptions: { - jsx: true, // tell vue-docgen-api that your components are using JSX to avoid conflicts with TypeScript syntax - }, getDestFile: (file, config) => path.join(config.outDir, "api.md"), templates: { component: (renderedUsage, doc) => diff --git a/docs/.vuepress/components/FinderExample.vue b/docs/.vuepress/components/FinderExample.vue index 59d1a11..e621f3a 100644 --- a/docs/.vuepress/components/FinderExample.vue +++ b/docs/.vuepress/components/FinderExample.vue @@ -1,10 +1,14 @@ diff --git a/docs/customization.md b/docs/customization.md index b6ecf27..2d3a9f1 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -71,75 +71,44 @@ Here are the available properties: | `dropZoneBgColor` | Background color of drop zones (visible when Drag & Drop) | | `draggedItemBgColor` | Background color of dragged items (visible when Drag & Drop) | -## Custom components +## Custom slots -You can pass your own components in order to customize some parts of the UI. +You can pass scoped slots in order to customize some parts of the UI. -### Item component +### Item -You can define a component to render items with the `itemComponent` prop. This component requires a `item` prop, that will -receive the data of the rendered item. +You can use the `item` scoped slot to render items. This slot accepts the following props: -```html - -``` - -```js -// ... -data() { - return { - itemComponent: { - props: ["item"], - template: - "
Name: {{ item.label }}
" - } - } -} -``` - - - -::: warning - -The example above uses the `template` option to define the rendering of the component, so -the [runtime compiler](https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only) is needed. - -You can also use a `render` function (in this case the runtime-only build is enough): +- `item`: the data of the item +- `expanded`: the expanded state of the item +- `dragged`: whether the item is currently dragged -```js -itemComponent: { - props: ["item"], - render(h) { - return h("div", this.item) - } -} +```html + + + ``` -::: + -### Arrow component +### Arrow -You can define a component to render arrows with the `arrowComponent` prop. This component accepts the following props: +You can use the `arrow` scoped slot to render custom arrows. This slot accepts the following props: - `expanded`: the expanded state of the item - `item`: the data of the item - `theme`: the theme applied on the `Finder` ```html - -``` - -```js -// ... -data() { - return { - arrowComponent: { - props: ["expanded", "item", "theme"], - template: - "
{{ expanded ? '↪' : '→' }}
" - } - } -} + + + ``` - + diff --git a/package.json b/package.json index fad977b..471f721 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "devDependencies": { "@babel/core": "^7.8.4", "@babel/eslint-parser": "^7.17.0", - "@babel/plugin-syntax-jsx": "^7.8.3", "@babel/preset-env": "^7.8.4", "@commitlint/cli": "^8.3.5", "@commitlint/config-conventional": "^8.3.4", @@ -72,10 +71,7 @@ "@storybook/builder-vite": "^7.5.3", "@storybook/vue3-vite": "^7.5.3", "@vitejs/plugin-vue": "^5.0.5", - "@vitejs/plugin-vue-jsx": "^4.0.0", "@vitest/coverage-v8": "^1.6.0", - "@vue/babel-plugin-jsx": "^1.2.2", - "@vue/babel-preset-jsx": "^1.4.0", "@vue/compat": "^3.4.31", "@vue/test-utils": "2.4.6", "@vuepress/plugin-register-components": "^2.0.0-beta.61", diff --git a/src/components/Finder.vue b/src/components/Finder.vue index fbff752..77b028c 100644 --- a/src/components/Finder.vue +++ b/src/components/Finder.vue @@ -1,57 +1,34 @@ - @@ -436,10 +388,5 @@ export default { position: relative; display: flex; align-items: stretch; - - .list-container { - display: flex; - align-items: stretch; - } } diff --git a/src/components/FinderItem.vue b/src/components/FinderItem.vue index 7f7a904..7bf6ef0 100644 --- a/src/components/FinderItem.vue +++ b/src/components/FinderItem.vue @@ -63,31 +63,26 @@ @click.stop @change="onSelect" /> - - - - + + {{ node.label }} + + + + > + + - + > + + @@ -106,6 +103,9 @@ import FinderListDropZone from "./FinderListDropZone.vue"; export default { name: "FinderItem", + components: { + FinderItemArrow, + }, mixins: [FinderListDropZone], props: { selectable: { @@ -129,12 +129,6 @@ export default { dragged() { return this.treeModel.isNodeDragged(this.node.id); }, - itemComponent() { - return this.options.itemComponent || "div"; - }, - arrowComponent() { - return this.options.arrowComponent || FinderItemArrow; - }, }, watch: { dragOver(newValue) { @@ -179,10 +173,13 @@ export default { return; } - if (this.options.dragImageComponent) { + if ( + this.$slots["drag-image"] && + this.$slots["drag-image"]({ item: this.node })[0]?.children.length + ) { this.showGhost = true; await this.$nextTick(); - event.dataTransfer.setDragImage(this.$refs.ghost.$el, 0, 0); + event.dataTransfer.setDragImage(this.$refs.ghost, 0, 0); } event.dataTransfer.setData("text/plain", this.node.id); diff --git a/src/components/FinderList.vue b/src/components/FinderList.vue index 5304d3b..d66f01f 100644 --- a/src/components/FinderList.vue +++ b/src/components/FinderList.vue @@ -1,34 +1,75 @@ + + + + + > + + + + +