feat: partial design-system migration

This commit is contained in:
Alex Grozav 2023-06-16 14:41:31 +03:00
parent 39581cbb81
commit 7841e55e91
99 changed files with 4109 additions and 4160 deletions

View file

@ -92,7 +92,6 @@
"qqjs>globby": "^11.1.0"
},
"patchedDependencies": {
"element-ui@2.15.12": "patches/element-ui@2.15.12.patch",
"typedi@0.10.0": "patches/typedi@0.10.0.patch",
"@sentry/cli@2.17.0": "patches/@sentry__cli@2.17.0.patch"
}

View file

@ -1,8 +0,0 @@
/**
* These icons are only defined for storybook build
* Editor icons are defined seperately
*/
import { library } from '@fortawesome/fontawesome-svg-core';
import { fas } from '@fortawesome/free-solid-svg-icons';
library.add(fas);

View file

@ -1,59 +1,58 @@
const path = require('path');
const { mergeConfig } = require('vite');
const { resolve } = require('path');
/**
* @type {import('@storybook/types').StorybookConfig}
*/
module.exports = {
framework: {
name: '@storybook/vue-webpack5',
options: {},
},
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.{ts,js}'],
stories: [
'../src/styleguide/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nActionBox/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nActionDropdown/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nActionToggle/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nAlert/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nAvatar/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nBadge/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nBlockUi/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nButton/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nCallout/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nCard/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nDatatable/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nHeading/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nIcon/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nIconButton/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nText/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nPopover/*.stories.@(js|jsx|ts|tsx)',
'../src/components/N8nTooltip/*.stories.@(js|jsx|ts|tsx)',
],
addons: [
'@storybook/addon-styling',
'@storybook/addon-links',
'@storybook/addon-essentials',
{
name: '@storybook/addon-postcss',
options: {
postcssLoaderOptions: {
implementation: require('postcss'),
},
},
},
'storybook-addon-themes',
// Disabled until this is actually used rather otherwise its a blank tab
// '@storybook/addon-interactions',
'@storybook/addon-a11y',
'storybook-dark-mode',
],
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.scss$/,
oneOf: [
{
resourceQuery: /module/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[path][name]__[local]--[hash:base64:5]',
},
},
},
'sass-loader',
],
include: path.resolve(__dirname, '../'),
},
{
use: ['vue-style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
},
],
staticDirs: ['../public'],
framework: {
name: '@storybook/vue3-vite',
options: {},
},
disableTelemetry: true,
async viteFinal(config, { configType }) {
// return the customized config
return mergeConfig(config, {
// customize the Vite config here
resolve: {
alias: [
{
find: /^@n8n-design-system\//,
replacement: `${resolve(__dirname, '..')}/src/`,
},
],
},
define: { 'process.env': {} },
});
config.resolve.alias = {
...config.resolve.alias,
'@/': path.resolve(__dirname, '../src/'),
};
return config;
},
docs: {
autodocs: true,
},
};

View file

@ -1,23 +1,34 @@
import './font-awesome-icons';
import { setup } from '@storybook/vue3';
import './storybook.scss';
import ElementUI from 'element-ui';
import lang from 'element-ui/lib/locale/lang/en';
import locale from 'element-ui/lib/locale';
import { library } from '@fortawesome/fontawesome-svg-core';
import { fas } from '@fortawesome/free-solid-svg-icons';
// import ElementUI from 'element-ui';
// import lang from 'element-ui/lib/locale/lang/en';
// import { locale } from 'element-plus';
import { N8nPlugin } from '../src/plugin';
import Vue from 'vue';
// import Vue from 'vue';
//
// Vue.use(ElementUI);
// Vue.use(N8nPlugin);
//
Vue.use(ElementUI);
Vue.use(N8nPlugin);
// // https://github.com/storybookjs/storybook/issues/6153
// Vue.prototype.toJSON = function () {
// return this;
// };
locale.use(lang);
setup((app) => {
library.add(fas);
// https://github.com/storybookjs/storybook/issues/6153
Vue.prototype.toJSON = function () {
return this;
};
// locale.use(lang);
app.use(N8nPlugin);
});
export const parameters = {
actions: {

View file

@ -1,11 +1,11 @@
@use './fonts.scss';
@use '~/src/css/base.scss' with (
$font-path: '~element-ui/lib/theme-chalk/fonts'
);
@use '../src/css/base.scss'; // with (
// $font-path: 'element-ui/lib/theme-chalk/fonts'
//);
@use '~/src/css/reset.scss';
@use '~/src/css/index.scss';
@use '../src/css/reset.scss';
@use '../src/css/index.scss';
.multi-container > * {
margin-bottom: 10px;

View file

@ -40,37 +40,43 @@
"devDependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/vue-fontawesome": "^2.0.9",
"@storybook/addon-actions": "^7.0.7",
"@storybook/addon-docs": "^7.0.7",
"@storybook/addon-essentials": "^7.0.7",
"@storybook/addon-links": "^7.0.7",
"@storybook/addon-postcss": "^3.0.0-alpha.1",
"@storybook/vue": "^7.0.7",
"@storybook/vue-webpack5": "^7.0.7",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@storybook/addon-a11y": "^7.0.21",
"@storybook/addon-actions": "^7.0.21",
"@storybook/addon-docs": "^7.0.21",
"@storybook/addon-essentials": "^7.0.21",
"@storybook/addon-links": "^7.0.21",
"@storybook/addon-postcss": "3.0.0-alpha.1",
"@storybook/addon-styling": "^1.3.0",
"@storybook/vue3": "^7.0.21",
"@storybook/vue3-vite": "^7.0.21",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/user-event": "^14.4.3",
"@testing-library/vue": "^5.8.3",
"@testing-library/vue": "^6.6.1",
"@types/markdown-it": "^12.2.3",
"@types/markdown-it-emoji": "^2.0.2",
"@types/markdown-it-link-attributes": "^3.0.1",
"@types/sanitize-html": "^2.8.0",
"autoprefixer": "^10.4.13",
"core-js": "^3.27.2",
"@types/sanitize-html": "^2.9.0",
"@vitejs/plugin-vue": "^4.2.3",
"autoprefixer": "^10.4.14",
"core-js": "^3.31.0",
"jsdom": "21.1.0",
"sass": "^1.58.0",
"sass-loader": "^13.2.0",
"storybook": "^7.0.7",
"storybook-addon-themes": "^6.1.0"
"sass": "^1.63.4",
"sass-loader": "^13.3.2",
"storybook": "^7.0.21",
"storybook-addon-themes": "^6.1.0",
"storybook-dark-mode": "^3.0.0"
},
"dependencies": {
"element-ui": "~2.15.12",
"element-plus": "^2.3.6",
"element-ui": "~2.15.13",
"markdown-it": "^13.0.1",
"markdown-it-emoji": "^2.0.2",
"markdown-it-link-attributes": "^4.0.1",
"markdown-it-task-lists": "^2.1.1",
"sanitize-html": "2.10.0",
"vue": "^2.7.14",
"vue": "^3.3.4",
"vue-boring-avatars": "^1.3.0",
"vue2-boring-avatars": "^0.3.8",
"xss": "^1.0.14"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -1,6 +1,6 @@
import N8nActionBox from './ActionBox.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/ActionBox',
@ -9,8 +9,8 @@ export default {
calloutTheme: {
control: {
type: 'select',
options: ['info', 'success', 'warning', 'danger', 'custom'],
},
options: ['info', 'success', 'warning', 'danger', 'custom'],
},
},
parameters: {
@ -23,11 +23,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nActionBox,
},
template: '<n8n-action-box v-bind="$props" @click="onClick" />',
template: '<n8n-action-box v-bind="args" @click="onClick" />',
methods,
});

View file

@ -1,5 +1,5 @@
import N8nActionDropdown from './ActionDropdown.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/ActionDropdown',
@ -8,8 +8,8 @@ export default {
placement: {
control: {
type: 'select',
options: ['top', 'top-end', 'top-start', 'bottom', 'bottom-end', 'bottom-start'],
},
options: ['top', 'top-end', 'top-start', 'bottom', 'bottom-end', 'bottom-start'],
},
activatorIcon: {
control: {
@ -19,18 +19,19 @@ export default {
trigger: {
control: {
type: 'select',
options: ['click', 'hover'],
},
options: ['click', 'hover'],
},
},
};
const template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nActionDropdown,
},
template: '<n8n-action-dropdown v-bind="$props" />',
template: '<n8n-action-dropdown v-bind="args" />',
});
export const defaultActionDropdown = template.bind({});

View file

@ -36,11 +36,7 @@
<script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue';
import {
Dropdown as ElDropdown,
DropdownMenu as ElDropdownMenu,
DropdownItem as ElDropdownItem,
} from 'element-ui';
import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus';
import N8nIcon from '../N8nIcon';
export interface IActionDropdownItem {
@ -104,12 +100,11 @@ export default defineComponent({
this.$emit('select', action);
},
onButtonBlur(event: FocusEvent): void {
const elementDropdown = this.$refs.elementDropdown as
| (Vue & { hide: () => void })
| undefined;
const elementDropdown = this.$refs.elementDropdown as InstanceType<ElDropdown>;
// Hide dropdown when clicking outside of current document
if (elementDropdown && event.relatedTarget === null) {
elementDropdown.hide();
if (elementDropdown?.handleClose && event.relatedTarget === null) {
elementDropdown.handleClose();
}
},
},

View file

@ -1,6 +1,6 @@
import N8nActionToggle from './ActionToggle.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/ActionToggle',
@ -25,12 +25,14 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nActionToggle,
},
template:
'<div style="height:300px;width:300px;display:flex;align-items:center;justify-content:center"><n8n-action-toggle v-bind="$props" @action="onAction" /></div>',
template: `<div style="height:300px; width:300px; display:flex; align-items:center; justify-content:center">
<n8n-action-toggle v-bind="args" @action="onAction" />
</div>`,
methods,
});

View file

@ -42,11 +42,7 @@
<script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue';
import {
Dropdown as ElDropdown,
DropdownMenu as ElDropdownMenu,
DropdownItem as ElDropdownItem,
} from 'element-ui';
import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus';
import N8nIcon from '../N8nIcon';
import type { UserAction } from '@/types';

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nAlert from './Alert.vue';
import N8nIcon from '../N8nIcon';
@ -18,12 +18,13 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nAlert,
},
template:
'<div style="position: relative; width: 100%; height: 300px;"><n8n-alert v-bind="$props"><template #aside>custom content slot</template></n8n-alert></div>',
'<div style="position: relative; width: 100%; height: 300px;"><n8n-alert v-bind="args"><template #aside>custom content slot</template></n8n-alert></div>',
});
export const ContentAsProps = Template.bind({});
@ -38,13 +39,14 @@ ContentAsProps.args = {
};
const TemplateForSlots: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nAlert,
N8nIcon,
},
template: `<div style="position: relative; width: 100%; height: 300px;">
<n8n-alert v-bind="$props">
<n8n-alert v-bind="args">
<template #title>Title</template>
<template>Description</template>
<template #aside><button>Button</button></template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nAvatar from './Avatar.vue';
export default {
@ -13,14 +13,16 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nAvatar,
},
template: '<n8n-avatar v-bind="$props" />',
template: '<n8n-avatar v-bind="args" />',
});
export const Avatar = Template.bind({});
Avatar.args = {
name: 'Sunny Side',
firstName: 'Sunny',
lastName: 'Side',
};

View file

@ -1,6 +1,6 @@
<template>
<span :class="['n8n-avatar', $style.container]" v-on="$listeners">
<avatar
<span :class="['n8n-avatar', $style.container]" v-bind="$attrs">
<Avatar
v-if="firstName"
:size="getSize(size)"
:name="firstName + ' ' + lastName"
@ -13,7 +13,7 @@
</template>
<script lang="ts">
import Avatar from 'vue2-boring-avatars';
import Avatar from 'vue-boring-avatars';
const sizes: { [size: string]: number } = {
small: 28,
@ -28,9 +28,11 @@ export default defineComponent({
props: {
firstName: {
type: String,
default: '',
},
lastName: {
type: String,
default: '',
},
size: {
type: String,
@ -47,7 +49,7 @@ export default defineComponent({
},
},
components: {
Avatar, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
Avatar,
},
computed: {
initials() {

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nBadge from './Badge.vue';
export default {
@ -17,11 +17,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nBadge,
},
template: '<n8n-badge v-bind="$props">Badge</n8n-badge>',
template: '<n8n-badge v-bind="args">Badge</n8n-badge>',
});
export const Badge = Template.bind({});

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nBlockUi from './BlockUi.vue';
export default {
@ -7,12 +7,13 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nBlockUi,
},
template:
'<div style="position: relative; width: 100%; height: 300px;"><n8n-block-ui v-bind="$props" /></div>',
'<div style="position: relative; width: 100%; height: 300px;"><n8n-block-ui v-bind="args" /></div>',
});
export const BlockUi = Template.bind({});

View file

@ -1,6 +1,6 @@
import N8nButton from './Button.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Button',
@ -13,8 +13,8 @@ export default {
size: {
control: {
type: 'select',
options: ['mini', 'small', 'medium', 'large', 'xlarge'],
},
options: ['mini', 'small', 'medium', 'large', 'xlarge'],
},
float: {
type: 'select',
@ -34,11 +34,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nButton,
},
template: '<n8n-button v-bind="$props" @click="onClick" />',
template: '<n8n-button v-bind="args" @click="onClick" />',
methods,
});
@ -48,48 +49,50 @@ Button.args = {
};
const AllSizesTemplate: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nButton,
},
template: `<div>
<n8n-button v-bind="$props" size="large" @click="onClick" />
<n8n-button v-bind="$props" size="medium" @click="onClick" />
<n8n-button v-bind="$props" size="small" @click="onClick" />
<n8n-button v-bind="$props" :loading="true" @click="onClick" />
<n8n-button v-bind="$props" :disabled="true" @click="onClick" />
<n8n-button v-bind="args" size="large" @click="onClick" />
<n8n-button v-bind="args" size="medium" @click="onClick" />
<n8n-button v-bind="args" size="small" @click="onClick" />
<n8n-button v-bind="args" :loading="true" @click="onClick" />
<n8n-button v-bind="args" :disabled="true" @click="onClick" />
</div>`,
methods,
});
const AllColorsAndSizesTemplate: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nButton,
},
template: `<div>
<n8n-button v-bind="$props" size="large" type="primary" @click="onClick" />
<n8n-button v-bind="$props" size="large" type="secondary" @click="onClick" />
<n8n-button v-bind="$props" size="large" type="tertiary" @click="onClick" />
<n8n-button v-bind="$props" size="large" type="success" @click="onClick" />
<n8n-button v-bind="$props" size="large" type="warning" @click="onClick" />
<n8n-button v-bind="$props" size="large" type="danger" @click="onClick" />
<n8n-button v-bind="args" size="large" type="primary" @click="onClick" />
<n8n-button v-bind="args" size="large" type="secondary" @click="onClick" />
<n8n-button v-bind="args" size="large" type="tertiary" @click="onClick" />
<n8n-button v-bind="args" size="large" type="success" @click="onClick" />
<n8n-button v-bind="args" size="large" type="warning" @click="onClick" />
<n8n-button v-bind="args" size="large" type="danger" @click="onClick" />
<br/>
<br/>
<n8n-button v-bind="$props" size="medium" type="primary" @click="onClick" />
<n8n-button v-bind="$props" size="medium" type="secondary" @click="onClick" />
<n8n-button v-bind="$props" size="medium" type="tertiary" @click="onClick" />
<n8n-button v-bind="$props" size="medium" type="success" @click="onClick" />
<n8n-button v-bind="$props" size="medium" type="warning" @click="onClick" />
<n8n-button v-bind="$props" size="medium" type="danger" @click="onClick" />
<n8n-button v-bind="args" size="medium" type="primary" @click="onClick" />
<n8n-button v-bind="args" size="medium" type="secondary" @click="onClick" />
<n8n-button v-bind="args" size="medium" type="tertiary" @click="onClick" />
<n8n-button v-bind="args" size="medium" type="success" @click="onClick" />
<n8n-button v-bind="args" size="medium" type="warning" @click="onClick" />
<n8n-button v-bind="args" size="medium" type="danger" @click="onClick" />
<br/>
<br/>
<n8n-button v-bind="$props" size="small" type="primary" @click="onClick" />
<n8n-button v-bind="$props" size="small" type="secondary" @click="onClick" />
<n8n-button v-bind="$props" size="small" type="tertiary" @click="onClick" />
<n8n-button v-bind="$props" size="small" type="success" @click="onClick" />
<n8n-button v-bind="$props" size="small" type="warning" @click="onClick" />
<n8n-button v-bind="$props" size="small" type="danger" @click="onClick" />
<n8n-button v-bind="args" size="small" type="primary" @click="onClick" />
<n8n-button v-bind="args" size="small" type="secondary" @click="onClick" />
<n8n-button v-bind="args" size="small" type="tertiary" @click="onClick" />
<n8n-button v-bind="args" size="small" type="success" @click="onClick" />
<n8n-button v-bind="args" size="small" type="warning" @click="onClick" />
<n8n-button v-bind="args" size="small" type="danger" @click="onClick" />
</div>`,
methods,
});

View file

@ -5,7 +5,7 @@
:aria-disabled="ariaDisabled"
:aria-busy="ariaBusy"
aria-live="polite"
v-on="$listeners"
v-bind="$attrs"
>
<span :class="$style.icon" v-if="loading || icon">
<n8n-spinner v-if="loading" :size="size" />

View file

@ -1,5 +1,5 @@
<template>
<n8n-button ref="button" v-bind="attrs" v-on="$listeners">
<n8n-button ref="button" v-bind="attrs" v-bind="$attrs">
<slot />
</n8n-button>
</template>

View file

@ -1,7 +1,7 @@
import N8nCallout from './Callout.vue';
import N8nLink from '../N8nLink';
import N8nText from '../N8nText';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Callout',
@ -10,8 +10,8 @@ export default {
theme: {
control: {
type: 'select',
options: ['info', 'secondary', 'success', 'warning', 'danger', 'custom'],
},
options: ['info', 'secondary', 'success', 'warning', 'danger', 'custom'],
},
message: {
control: {
@ -41,6 +41,7 @@ interface Args {
}
const template: StoryFn<Args> = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nLink,
@ -48,7 +49,7 @@ const template: StoryFn<Args> = (args, { argTypes }) => ({
N8nCallout,
},
template: `
<n8n-callout v-bind="$props">
<n8n-callout v-bind="args">
${args.default}
<template #actions v-if="actions">
${args.actions}

View file

@ -1,5 +1,5 @@
import N8nCard from './Card.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nButton from '../N8nButton/Button.vue';
import N8nIcon from '../N8nIcon/Icon.vue';
import N8nText from '../N8nText/Text.vue';
@ -14,7 +14,7 @@ export const Default: StoryFn = (args, { argTypes }) => ({
components: {
N8nCard,
},
template: '<n8n-card v-bind="$props">This is a card.</n8n-card>',
template: '<n8n-card v-bind="args">This is a card.</n8n-card>',
});
export const Hoverable: StoryFn = (args, { argTypes }) => ({
@ -25,7 +25,7 @@ export const Hoverable: StoryFn = (args, { argTypes }) => ({
N8nText,
},
template: `<div style="width: 140px; text-align: center;">
<n8n-card v-bind="$props">
<n8n-card v-bind="args">
<n8n-icon icon="plus" size="xlarge" />
<n8n-text size="large" class="mt-2xs">Add</n8n-text>
</n8n-card>
@ -44,7 +44,7 @@ export const WithSlots: StoryFn = (args, { argTypes }) => ({
N8nIcon,
N8nText,
},
template: `<n8n-card v-bind="$props">
template: `<n8n-card v-bind="args">
<template slot="prepend">
<n8n-icon icon="check" size="large" />
</template>

View file

@ -1,5 +1,5 @@
<template>
<div :class="classes" v-on="$listeners">
<div :class="classes" v-bind="$attrs">
<div :class="$style.icon" v-if="$slots.prepend">
<slot name="prepend" />
</div>

View file

@ -1,5 +1,5 @@
import N8nCheckbox from './Checkbox.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import { action } from '@storybook/addon-actions';
export default {
@ -21,7 +21,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
data: () => ({
isChecked: false,
}),
template: '<n8n-checkbox v-model="isChecked" v-bind="$props" @input="onInput"></n8n-checkbox>',
template: '<n8n-checkbox v-model="isChecked" v-bind="args" @input="onInput"></n8n-checkbox>',
methods,
});

View file

@ -1,5 +1,5 @@
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nColorPicker from './ColorPicker.vue';
export default {
@ -44,7 +44,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
color: null,
}),
template:
'<n8n-color-picker v-model="color" v-bind="$props" @input="onInput" @change="onChange" @active-change="onActiveChange" />',
'<n8n-color-picker v-model="color" v-bind="args" @input="onInput" @change="onChange" @active-change="onActiveChange" />',
methods,
});

View file

@ -1,5 +1,5 @@
import N8nDatatable from './Datatable.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import { rows, columns } from './__tests__/data';
export default {
@ -8,11 +8,12 @@ export default {
};
export const Default: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nDatatable,
},
template: '<n8n-datatable v-bind="$props"></n8n-datatable>',
template: '<n8n-datatable v-bind="args"></n8n-datatable>',
});
Default.args = {

View file

@ -114,7 +114,7 @@ export default defineComponent({
</script>
<template>
<div :class="classes" v-on="$listeners">
<div :class="classes" v-bind="$attrs">
<table :class="$style.datatable">
<thead :class="$style.datatableHeader">
<tr>
@ -158,7 +158,7 @@ export default defineComponent({
<n8n-select
size="mini"
:value="rowsPerPage"
@input="onRowsPerPageChange"
@update:modelValue="onRowsPerPageChange"
popper-append-to-body
>
<template #prepend>{{ t('datatable.pageSize') }}</template>

View file

@ -1,6 +1,6 @@
import N8nFormBox from './FormBox.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Modules/FormBox',
@ -17,11 +17,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nFormBox,
},
template: '<n8n-form-box v-bind="$props" @submit="onSubmit" @input="onInput" />',
template: '<n8n-form-box v-bind="args" @submit="onSubmit" @input="onInput" />',
methods,
});

View file

@ -1,6 +1,6 @@
import N8nFormInput from './FormInput.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Modules/FormInput',
@ -15,12 +15,13 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nFormInput,
},
template: `
<n8n-form-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" />
<n8n-form-input v-bind="args" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" />
`,
methods,
data() {

View file

@ -1,6 +1,6 @@
import N8nFormInputs from './FormInputs.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Modules/FormInputs',
@ -17,11 +17,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nFormInputs,
},
template: '<n8n-form-inputs v-bind="$props" @submit="onSubmit" @input="onInput" />',
template: '<n8n-form-inputs v-bind="args" @submit="onSubmit" @input="onInput" />',
methods,
});

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nHeading from './Heading.vue';
export default {
@ -8,24 +8,25 @@ export default {
size: {
control: {
type: 'select',
options: ['2xlarge', 'xlarge', 'large', 'medium', 'small'],
},
options: ['2xlarge', 'xlarge', 'large', 'medium', 'small'],
},
color: {
control: {
type: 'select',
options: ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'],
},
options: ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'],
},
},
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nHeading,
},
template: '<n8n-heading v-bind="$props">hello world</n8n-heading>',
template: '<n8n-heading v-bind="args">hello world</n8n-heading>',
});
export const Heading = Template.bind({});

View file

@ -1,5 +1,5 @@
<template>
<component :is="tag" :class="['n8n-heading', ...classes]" v-on="$listeners">
<component :is="tag" :class="['n8n-heading', ...classes]" v-bind="$attrs">
<slot></slot>
</component>
</template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nIcon from './Icon.vue';
export default {
@ -11,8 +11,8 @@ export default {
size: {
control: {
type: 'select',
options: ['xsmall', 'small', 'medium', 'large'],
},
options: ['xsmall', 'small', 'medium', 'large'],
},
spin: {
control: {
@ -23,11 +23,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nIcon,
},
template: '<n8n-icon v-bind="$props" />',
template: '<n8n-icon v-bind="args" />',
});
export const Clock = Template.bind({});

View file

@ -1,5 +1,5 @@
<template>
<n8n-text :size="size" :color="color" :compact="true" class="n8n-icon" v-on="$listeners">
<n8n-text :size="size" :color="color" :compact="true" class="n8n-icon" v-bind="$attrs">
<font-awesome-icon :icon="icon" :spin="spin" :class="$style[size]" />
</n8n-text>
</template>

View file

@ -1,6 +1,6 @@
import N8nIconButton from './IconButton.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Icon Button',
@ -13,8 +13,8 @@ export default {
size: {
control: {
type: 'select',
options: ['mini', 'small', 'medium', 'large', 'xlarge'],
},
options: ['mini', 'small', 'medium', 'large', 'xlarge'],
},
},
parameters: {
@ -27,11 +27,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nIconButton,
},
template: '<n8n-icon-button v-bind="$props" @click="onClick" />',
template: '<n8n-icon-button @click="onClick" v-bind="args" />',
methods,
});
@ -42,12 +43,13 @@ Button.args = {
};
const ManyTemplate: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nIconButton,
},
template:
'<div> <n8n-icon-button v-bind="$props" size="xlarge" @click="onClick" /> <n8n-icon-button v-bind="$props" size="large" @click="onClick" /> <n8n-icon-button v-bind="$props" size="medium" @click="onClick" /> <n8n-icon-button v-bind="$props" size="small" @click="onClick" /> <n8n-icon-button v-bind="$props" :loading="true" @click="onClick" /> <n8n-icon-button v-bind="$props" :disabled="true" @click="onClick" /></div>',
'<div> <n8n-icon-button v-bind="args" size="xlarge" @click="onClick" /> <n8n-icon-button v-bind="args" size="large" @click="onClick" /> <n8n-icon-button v-bind="args" size="medium" @click="onClick" /> <n8n-icon-button v-bind="args" size="small" @click="onClick" /> <n8n-icon-button v-bind="args" :loading="true" @click="onClick" /> <n8n-icon-button v-bind="args" :disabled="true" @click="onClick" /></div>',
methods,
});

View file

@ -1,5 +1,5 @@
<template>
<n8n-button square v-bind="$props" v-on="$listeners" />
<n8n-button square v-bind="{ ...$attrs, ...$props }" />
</template>
<script lang="ts">

View file

@ -1,5 +1,5 @@
import N8nInfoAccordion from './InfoAccordion.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import { action } from '@storybook/addon-actions';
export default {
@ -20,7 +20,7 @@ export const Default: StoryFn = (args, { argTypes }) => ({
components: {
N8nInfoAccordion,
},
template: '<n8n-info-accordion v-bind="$props" @click="onClick" />',
template: '<n8n-info-accordion v-bind="args" @click="onClick" />',
methods,
});

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nInfoTip from './InfoTip.vue';
export default {
@ -7,12 +7,13 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nInfoTip,
},
template:
'<n8n-info-tip v-bind="$props">Need help doing something? <a href="/docs" target="_blank">Open docs</a></n8n-info-tip>',
'<n8n-info-tip v-bind="args">Need help doing something? <a href="/docs" target="_blank">Open docs</a></n8n-info-tip>',
});
export const Note = Template.bind({});

View file

@ -1,7 +1,7 @@
import N8nInput from './Input.vue';
import N8nIcon from '../N8nIcon';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Input',
@ -36,12 +36,13 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nInput,
},
template:
'<n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" />',
'<n8n-input v-bind="args" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" />',
data() {
return {
val: '',
@ -61,7 +62,7 @@ const ManyTemplate: StoryFn = (args, { argTypes }) => ({
N8nInput,
},
template:
'<div class="multi-container"> <n8n-input size="xlarge" v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" size="medium" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" size="small" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="$props" v-model="val" size="mini" @input="onInput" @change="onChange" @focus="onFocus" /> </div> ',
'<div class="multi-container"> <n8n-input size="xlarge" v-bind="args" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="args" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="args" size="medium" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="args" size="small" v-model="val" @input="onInput" @change="onChange" @focus="onFocus" /> <n8n-input v-bind="args" v-model="val" size="mini" @input="onInput" @change="onChange" @focus="onFocus" /> </div> ',
methods,
data() {
return {
@ -89,7 +90,7 @@ const WithPrefix: StoryFn = (args, { argTypes }) => ({
N8nInput,
},
template:
'<n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus"><n8n-icon icon="clock" slot="prefix" /></n8n-input>',
'<n8n-input v-bind="args" v-model="val" @input="onInput" @change="onChange" @focus="onFocus"><n8n-icon icon="clock" slot="prefix" /></n8n-input>',
data() {
return {
val: '',
@ -110,7 +111,7 @@ const WithSuffix: StoryFn = (args, { argTypes }) => ({
N8nInput,
},
template:
'<n8n-input v-bind="$props" v-model="val" @input="onInput" @change="onChange" @focus="onFocus"><n8n-icon icon="clock" slot="suffix" /></n8n-input>',
'<n8n-input v-bind="args" v-model="val" @input="onInput" @change="onChange" @focus="onFocus"><n8n-icon icon="clock" slot="suffix" /></n8n-input>',
data() {
return {
val: '',

View file

@ -5,7 +5,7 @@
:class="['n8n-input', ...classes]"
:autoComplete="autocomplete"
ref="innerInput"
v-on="$listeners"
v-bind="$attrs"
:name="name"
>
<template #prepend>

View file

@ -1,6 +1,6 @@
import N8nInputLabel from './InputLabel.vue';
import N8nInput from '../N8nInput';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Input Label',
@ -12,13 +12,14 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nInputLabel,
N8nInput,
},
template:
'<div style="margin-top:50px"><n8n-input-label v-bind="$props"><n8n-input /></n8n-input-label></div>',
'<div style="margin-top:50px"><n8n-input-label v-bind="args"><n8n-input /></n8n-input-label></div>',
});
export const InputLabel = Template.bind({});

View file

@ -1,5 +1,5 @@
<template>
<div :class="$style.container" v-on="$listeners">
<div :class="$style.container" v-bind="$attrs">
<label
v-if="label || $slots.options"
:for="inputName"

View file

@ -1,6 +1,6 @@
import N8nInputNumber from './InputNumber.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Input Number',
@ -53,11 +53,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nInputNumber,
},
template: '<n8n-input-number v-bind="$props" v-model="val" @input="onInput" />',
template: '<n8n-input-number v-bind="args" v-model="val" @input="onInput" />',
data() {
return {
val: null,
@ -78,7 +79,7 @@ const ManyTemplate: StoryFn = (args, { argTypes }) => ({
N8nInputNumber,
},
template:
'<div> <n8n-input-number style="margin-bottom:10px" v-bind="$props" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="$props" size="medium" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="$props" size="small" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="$props" v-model="val" size="mini" @input="onInput" /> </div>',
'<div> <n8n-input-number style="margin-bottom:10px" v-bind="args" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="args" size="medium" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="args" size="small" v-model="val" @input="onInput" /> <n8n-input-number style="margin-bottom:10px" v-bind="args" v-model="val" size="mini" @input="onInput" /> </div>',
methods,
data() {
return {

View file

@ -1,6 +1,6 @@
import N8nLink from './Link.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Link',
@ -9,8 +9,8 @@ export default {
size: {
control: {
type: 'select',
options: ['small', 'medium', 'large'],
},
options: ['small', 'medium', 'large'],
},
},
};
@ -20,11 +20,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nLink,
},
template: '<n8n-link v-bind="$props" @click="onClick">hello world</n8n-link>',
template: '<n8n-link v-bind="args" @click="onClick">hello world</n8n-link>',
methods,
});

View file

@ -1,5 +1,5 @@
<template>
<n8n-route :to="to" :newWindow="newWindow" v-on="$listeners" class="n8n-link">
<n8n-route :to="to" :newWindow="newWindow" v-bind="$attrs" class="n8n-link">
<span :class="$style[`${underline ? `${theme}-underline` : theme}`]">
<n8n-text :size="size" :bold="bold">
<slot></slot>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nLoading from './Loading.vue';
export default {
@ -18,24 +18,25 @@ export default {
rows: {
control: {
type: 'select',
options: [1, 2, 3, 4, 5],
},
options: [1, 2, 3, 4, 5],
},
variant: {
control: {
type: 'select',
options: ['button', 'h1', 'image', 'p'],
},
options: ['button', 'h1', 'image', 'p'],
},
},
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nLoading,
},
template: '<n8n-loading v-bind="$props"></n8n-loading>',
template: '<n8n-loading v-bind="args"></n8n-loading>',
});
export const Loading = Template.bind({});

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nMarkdown from './Markdown.vue';
export default {
@ -18,24 +18,25 @@ export default {
loadingBlocks: {
control: {
type: 'select',
options: [1, 2, 3, 4, 5],
},
options: [1, 2, 3, 4, 5],
},
loadingRows: {
control: {
type: 'select',
options: [1, 2, 3, 4, 5],
},
options: [1, 2, 3, 4, 5],
},
},
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nMarkdown,
},
template: '<n8n-markdown v-bind="$props"></n8n-markdown>',
template: '<n8n-markdown v-bind="args"></n8n-markdown>',
});
export const Markdown = Template.bind({});

View file

@ -1,7 +1,7 @@
import N8nMenu from './Menu.vue';
import N8nIcon from '../N8nIcon';
import N8nText from '../N8nText';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import { action } from '@storybook/addon-actions';
export default {
@ -15,19 +15,21 @@ const methods = {
};
const template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nMenu,
},
template: `
<div style="height: 90vh; width: 200px">
<n8n-menu v-bind="$props" @select="onSelect"></n8n-menu>
<n8n-menu v-bind="args" @select="onSelect"></n8n-menu>
</div>
`,
methods,
});
const templateWithHeaderAndFooter: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nMenu,
@ -36,7 +38,7 @@ const templateWithHeaderAndFooter: StoryFn = (args, { argTypes }) => ({
},
template: `
<div style="height: 90vh; width: 200px">
<n8n-menu v-bind="$props" @select="onSelect">
<n8n-menu v-bind="args" @select="onSelect">
<template #header>
<a href="#" class="p-m hideme" style="display: block;">
<n8n-icon icon="long-arrow-alt-left"/>&nbsp;&nbsp;Back to home
@ -55,6 +57,7 @@ const templateWithHeaderAndFooter: StoryFn = (args, { argTypes }) => ({
});
const templateWithAllSlots: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nMenu,
@ -63,7 +66,7 @@ const templateWithAllSlots: StoryFn = (args, { argTypes }) => ({
},
template: `
<div style="height: 90vh; width: 200px">
<n8n-menu v-bind="$props" @select="onSelect">
<n8n-menu v-bind="args" @select="onSelect">
<template #header>
<a href="#" class="p-m hideme" style="display: block;">
<n8n-icon icon="long-arrow-alt-left"/>&nbsp;&nbsp;Back to home

View file

@ -14,7 +14,7 @@
<div v-if="$slots.menuPrefix" :class="$style.menuPrefix">
<slot name="menuPrefix"></slot>
</div>
<el-menu :defaultActive="defaultActive" :collapse="collapsed" v-on="$listeners">
<el-menu :defaultActive="defaultActive" :collapse="collapsed" v-bind="$attrs">
<n8n-menu-item
v-for="item in upperMenuItems"
:key="item.id"
@ -29,7 +29,7 @@
</div>
<div :class="[$style.lowerContent, 'pb-2xs']">
<slot name="beforeLowerMenu"></slot>
<el-menu :defaultActive="defaultActive" :collapse="collapsed" v-on="$listeners">
<el-menu :defaultActive="defaultActive" :collapse="collapsed" v-bind="$attrs">
<n8n-menu-item
v-for="item in lowerMenuItems"
:key="item.id"

View file

@ -1,6 +1,6 @@
import N8nMenuItem from '.';
import { Menu as ElMenu } from 'element-ui';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/MenuItem',
@ -8,6 +8,7 @@ export default {
};
const template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
ElMenu,
@ -16,7 +17,7 @@ const template: StoryFn = (args, { argTypes }) => ({
template: `
<div style="width: 200px">
<el-menu>
<n8n-menu-item v-bind="$props" />
<n8n-menu-item v-bind="args" />
</el-menu>
</div>
`,

View file

@ -1,5 +1,5 @@
import N8nNodeCreatorNode from './NodeCreatorNode.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Modules/Node Creator Node',
@ -12,7 +12,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
N8nNodeCreatorNode,
},
template: `
<n8n-node-creator-node v-bind="$props">
<n8n-node-creator-node v-bind="args">
<template v-slot:icon>
<img src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/cartman.svg" />
</template>
@ -39,7 +39,7 @@ const PanelTemplate: StoryFn = (args, { argTypes }) => ({
};
},
template: `
<n8n-node-creator-node v-bind="$props" :isPanelActive="isPanelActive" @click.capture="isPanelActive = true">
<n8n-node-creator-node v-bind="args" :isPanelActive="isPanelActive" @click.capture="isPanelActive = true">
<template v-slot:icon>
<img src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/cartman.svg" />
</template>

View file

@ -4,7 +4,7 @@
[$style.creatorNode]: true,
[$style.hasAction]: !showActionArrow,
}"
v-on="$listeners"
v-bind="$attrs"
v-bind="$attrs"
>
<div :class="$style.nodeIcon">

View file

@ -1,5 +1,5 @@
import N8nNodeIcon from './NodeIcon.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/NodeIcon',
@ -11,7 +11,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
components: {
N8nNodeIcon,
},
template: '<n8n-node-icon v-bind="$props"></n8n-node-icon>',
template: '<n8n-node-icon v-bind="args"></n8n-node-icon>',
});
export const FileIcon = DefaultTemplate.bind({});

View file

@ -7,7 +7,7 @@
[$style.disabled]: disabled,
}"
:style="iconStyleData"
v-on="$listeners"
v-bind="$attrs"
>
<!-- ElementUI tooltip is prone to memory-leaking so we only render it if we really need it -->
<n8n-tooltip placement="top" :disabled="!showTooltip" v-if="showTooltip">

View file

@ -1,5 +1,5 @@
import N8nNotice from './Notice.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Notice',
@ -18,7 +18,7 @@ const SlotTemplate: StoryFn = (args, { argTypes }) => ({
N8nNotice,
},
template:
'<n8n-notice v-bind="$props">This is a notice! Thread carefully from this point forward.</n8n-notice>',
'<n8n-notice v-bind="args">This is a notice! Thread carefully from this point forward.</n8n-notice>',
});
const PropTemplate: StoryFn = (args, { argTypes }) => ({
@ -26,7 +26,7 @@ const PropTemplate: StoryFn = (args, { argTypes }) => ({
components: {
N8nNotice,
},
template: '<n8n-notice v-bind="$props"/>',
template: '<n8n-notice v-bind="args"/>',
});
export const Warning = SlotTemplate.bind({});

View file

@ -1,4 +1,17 @@
<script lang="ts">
import { Option } from 'element-ui';
export default Option;
import { ElOption } from 'element-plus';
import { defineComponent } from 'vue';
export default defineComponent({
props: {
...ElOption.props,
},
components: {
ElOption,
},
});
</script>
<template>
<el-option v-bind="{ ...$props, ...$attrs }"><slot /></el-option>
</template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nPagination from './Pagination.vue';
export default {
@ -7,11 +7,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nPagination,
},
template: '<n8n-pagination v-bind="$props" />',
template: '<n8n-pagination v-bind="args" />',
});
export const Pagination: StoryFn = Template.bind({});

View file

@ -1,10 +1,11 @@
<script lang="ts">
import type { DefineComponent } from 'vue';
import { defineComponent } from 'vue';
import { Pagination as ElPagination } from 'element-ui';
import { ElPagination } from 'element-plus';
export default defineComponent({
props: (ElPagination as unknown as DefineComponent).props,
props: {
...ElPagination.props,
},
components: {
ElPagination,
},
@ -12,10 +13,5 @@ export default defineComponent({
</script>
<template>
<el-pagination
background
layout="prev, pager, next"
v-bind="[$props, $attrs]"
v-on="$listeners"
/>
<el-pagination background layout="prev, pager, next" v-bind="{ ...$props, ...$attrs }" />
</template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nPopover from './Popover.vue';
export default {
@ -36,12 +36,19 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nPopover,
},
template:
'<n8n-Popover v-bind="$props"><div style="margin:50px; display: inline-block;"><span>yo</span></div></n8n-Popover>',
template: `<n8n-popover v-bind="args">
<div style="margin:50px; display: inline-block;">
<span>yo</span>
</div>
<template #content>
Popover
</template>
</n8n-popover>`,
});
export const Popover = Template.bind({});

View file

@ -1,4 +1,23 @@
<script lang="ts">
import { Popover } from 'element-ui';
export default Popover;
import { ElPopover } from 'element-plus';
import { defineComponent } from 'vue';
export default defineComponent({
name: 'N8nPopover',
props: {
...ElPopover.props,
},
components: {
ElPopover,
},
});
</script>
<template>
<el-popover v-bind="{ ...$props, ...$attrs }">
<slot />
<template #content>
<slot name="content" />
</template>
</el-popover>
</template>

View file

@ -1,5 +1,5 @@
import N8nPulse from './Pulse.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Pulse',

View file

@ -1,7 +1,7 @@
import N8nRadioButtons from './RadioButtons.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/RadioButtons',
@ -22,11 +22,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nRadioButtons,
},
template: `<n8n-radio-buttons v-model="val" v-bind="$props" @input="onInput">
template: `<n8n-radio-buttons v-model="val" v-bind="args" @input="onInput">
</n8n-radio-buttons>`,
methods,
data() {

View file

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nRecycleScroller from './RecycleScroller.vue';
import type { ComponentInstance } from 'vue';
@ -42,7 +42,7 @@ const Template: StoryFn = () => ({
},
},
template: `<div style="height: calc(100vh - 30px); width: 100%; overflow: auto">
<N8nRecycleScroller :items="items" :item-size="100" item-key="id" v-bind="$props">
<N8nRecycleScroller :items="items" :item-size="100" item-key="id" v-bind="args">
<template #default="{ item, updateItemSize }">
<div
:ref="'item-' + item.id"

View file

@ -18,6 +18,7 @@ const methods = {
};
const Template = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nResizeWrapper,

View file

@ -1,9 +1,9 @@
<template>
<span>
<router-link v-if="useRouterLink" :to="to" v-on="$listeners">
<router-link v-if="useRouterLink" :to="to" v-bind="$attrs">
<slot></slot>
</router-link>
<a v-else :href="to" :target="openNewWindow ? '_blank' : '_self'" v-on="$listeners">
<a v-else :href="to" :target="openNewWindow ? '_blank' : '_self'" v-bind="$attrs">
<slot></slot>
</a>
</span>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nSelect from './Select.vue';
import N8nOption from '../N8nOption';
import N8nIcon from '../N8nIcon';
@ -16,8 +16,8 @@ export default {
size: {
control: {
type: 'select',
options: ['large', 'medium', 'small', 'mini'],
},
options: ['large', 'medium', 'small', 'mini'],
},
loading: {
control: {
@ -46,6 +46,7 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nSelect,
@ -53,7 +54,7 @@ const Template: StoryFn = (args, { argTypes }) => ({
N8nIcon,
},
template:
'<n8n-select v-bind="$props" v-model="val" @input="onInput" @change="onChange"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>',
'<n8n-select v-bind="args" v-model="val" @input="onInput" @change="onChange"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>',
data() {
return {
val: '',
@ -73,7 +74,7 @@ Filterable.args = {
const selects = ['large', 'medium', 'small', 'mini']
.map(
(size) =>
`<n8n-select v-bind="$props" v-model="val" @input="onInput" @change="onChange" size="${size}"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>`,
`<n8n-select v-bind="args" v-model="val" @input="onInput" @change="onChange" size="${size}"><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>`,
)
.join('');
@ -103,7 +104,7 @@ Sizes.args = {
const selectsWithIcon = ['xlarge', 'large', 'medium', 'small', 'mini']
.map(
(size) =>
`<n8n-select v-bind="$props" v-model="val" @input="onInput" size="${size}"><n8n-icon icon="search" slot="prefix" /><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>`,
`<n8n-select v-bind="args" v-model="val" @input="onInput" size="${size}"><n8n-icon icon="search" slot="prefix" /><n8n-option value="1">op1</n8n-option><n8n-option value="2">op2</n8n-option></n8n-select>`,
)
.join('');
@ -138,7 +139,7 @@ const LimitedWidthTemplate: StoryFn = (args, { argTypes }) => ({
N8nIcon,
},
template:
'<div style="width:100px;"><n8n-select v-bind="$props" v-model="val" @input="onInput" @change="onChange"><n8n-option value="1" label="opt1 11 1111" /><n8n-option value="2" label="opt2 test very long ipsum"/></n8n-select></div>',
'<div style="width:100px;"><n8n-select v-bind="args" v-model="val" @input="onInput" @change="onChange"><n8n-option value="1" label="opt1 11 1111" /><n8n-option value="2" label="opt2 test very long ipsum"/></n8n-select></div>',
data() {
return {
val: '',

View file

@ -10,12 +10,11 @@
<slot name="prepend" />
</div>
<el-select
v-bind="$props"
:value="value"
v-bind="{ ...$props, ...$attrs }"
:modelValue="modelValue"
:size="computedSize"
:class="$style[classes]"
:popper-class="popperClass"
v-on="$listeners"
ref="innerSelect"
>
<template #prefix>
@ -32,7 +31,7 @@
</template>
<script lang="ts">
import { Select as ElSelect } from 'element-ui';
import { ElSelect } from 'element-plus';
import { defineComponent } from 'vue';
type InnerSelectRef = InstanceType<typeof ElSelect>;
@ -49,7 +48,8 @@ export default defineComponent({
ElSelect,
},
props: {
value: {},
...ElSelect.props,
modelValue: {},
size: {
type: String,
default: 'large',

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nSpinner from './Spinner.vue';
export default {
@ -8,24 +8,25 @@ export default {
size: {
control: {
type: 'select',
options: ['small', 'medium', 'large'],
},
options: ['small', 'medium', 'large'],
},
type: {
control: {
type: 'select',
options: ['dots', 'ring'],
},
options: ['dots', 'ring'],
},
},
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nSpinner,
},
template: '<n8n-spinner v-bind="$props" />',
template: '<n8n-spinner v-bind="args" />',
});
export const Spinner = Template.bind({});

View file

@ -1,5 +1,5 @@
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nSticky from './Sticky.vue';
export default {
@ -47,12 +47,13 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nSticky,
},
template:
'<n8n-sticky v-bind="$props" @resize="onResize" @resizeend="onResizeEnd" @resizeStart="onResizeStart" @input="onInput"></n8n-sticky>',
'<n8n-sticky v-bind="args" @resize="onResize" @resizeend="onResizeEnd" @resizeStart="onResizeStart" @input="onInput"></n8n-sticky>',
methods,
});

View file

@ -1,7 +1,7 @@
import N8nTabs from './Tabs.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Tabs',
@ -17,11 +17,12 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nTabs,
},
template: `<n8n-tabs v-model="val" v-bind="$props" @input="onInput">
template: `<n8n-tabs v-model="val" v-bind="args" @input="onInput">
</n8n-tabs>`,
methods,
data() {

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nTag from './Tag.vue';
export default {
@ -14,11 +14,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nTag,
},
template: '<n8n-tag v-bind="$props"></n8n-tag>',
template: '<n8n-tag v-bind="args"></n8n-tag>',
});
export const Tag = Template.bind({});

View file

@ -1,5 +1,5 @@
<template>
<span :class="['n8n-tag', $style.tag]" v-on="$listeners">
<span :class="['n8n-tag', $style.tag]" v-bind="$attrs">
{{ text }}
</span>
</template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nTags from './Tags.vue';
export default {
@ -8,11 +8,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nTags,
},
template: '<n8n-tags v-bind="$props"></n8n-tags>',
template: '<n8n-tags v-bind="args"></n8n-tags>',
});
export const Tags = Template.bind({});

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nText from './Text.vue';
export default {
@ -8,32 +8,33 @@ export default {
size: {
control: {
type: 'select',
options: ['xsmall', 'small', 'medium', 'large'],
},
options: ['xsmall', 'small', 'medium', 'large'],
},
color: {
control: {
type: 'select',
options: [
'primary',
'text-dark',
'text-base',
'text-light',
'text-xlight',
'danger',
'success',
],
},
options: [
'primary',
'text-dark',
'text-base',
'text-light',
'text-xlight',
'danger',
'success',
],
},
},
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nText,
},
template: '<n8n-text v-bind="$props">hello world</n8n-text>',
template: '<n8n-text v-bind="args">hello world</n8n-text>',
});
export const Text = Template.bind({});

View file

@ -1,5 +1,5 @@
<template>
<component :is="tag" :class="['n8n-text', ...classes]" v-on="$listeners">
<component :is="tag" :class="['n8n-text', ...classes]" v-bind="$attrs">
<slot></slot>
</component>
</template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nTooltip from './Tooltip.vue';
export default {
@ -36,12 +36,13 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nTooltip,
},
template:
'<n8n-tooltip v-bind="$props"><div style="margin:50px; display: inline-block;"><span>yo</span></div></n8n-tooltip>',
'<n8n-tooltip v-bind="args"><div style="margin:50px; display: inline-block;"><span>yo</span></div></n8n-tooltip>',
});
export const Tooltip = Template.bind({});

View file

@ -1,5 +1,5 @@
<template>
<el-tooltip v-bind="$attrs">
<el-tooltip v-bind="{ ...$props, ...$attrs }">
<template v-for="(_, slotName) in $slots" #[slotName]>
<slot :name="slotName" />
<div
@ -22,7 +22,7 @@
<script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue';
import { Tooltip as ElTooltip } from 'element-ui';
import { ElTooltip } from 'element-plus';
import type { IN8nButton } from '@/types';
import N8nButton from '../N8nButton';
@ -34,6 +34,7 @@ export default defineComponent({
N8nButton,
},
props: {
...ElTooltip.props,
justifyButtons: {
type: String,
default: 'flex-end',

View file

@ -1,5 +1,5 @@
import N8nTree from './Tree.vue';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Atoms/Tree',
@ -11,7 +11,7 @@ export const Default: StoryFn = (args, { argTypes }) => ({
components: {
N8nTree,
},
template: `<n8n-tree v-bind="$props">
template: `<n8n-tree v-bind="args">
<template v-slot:label="{ label }">
<span>{{ label }}</span>
</template>

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import N8nUserInfo from './UserInfo.vue';
export default {
@ -10,11 +10,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nUserInfo,
},
template: '<n8n-user-info v-bind="$props" />',
template: '<n8n-user-info v-bind="args" />',
});
export const Member = Template.bind({});

View file

@ -1,6 +1,6 @@
import N8nUserSelect from './UserSelect.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Modules/UserSelect',
@ -18,12 +18,13 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nUserSelect,
},
template:
'<n8n-user-select v-bind="$props" v-model="val" @change="onChange" @blur="onBlur" @focus="onFocus" />',
'<n8n-user-select v-bind="args" v-model="val" @change="onChange" @blur="onBlur" @focus="onFocus" />',
methods,
data() {
return {

View file

@ -1,6 +1,6 @@
import N8nUsersList from './UsersList.vue';
import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import type { IUser } from '@/types';
export default {
@ -18,12 +18,13 @@ const methods = {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nUsersList,
},
template:
'<n8n-users-list v-bind="$props" :actions="actions" @reinvite="onReinvite" @delete="onDelete" />',
'<n8n-users-list v-bind="args" :actions="actions" @reinvite="onReinvite" @delete="onDelete" />',
methods,
});

View file

@ -6,46 +6,46 @@ export { default as N8nAvatar } from './N8nAvatar';
export { default as N8nBadge } from './N8nBadge';
export { default as N8nBlockUi } from './N8nBlockUi';
export { default as N8nButton } from './N8nButton';
export { N8nElButton } from './N8nButton/overrides';
// export { N8nElButton } from './N8nButton/overrides';
export { default as N8nCallout } from './N8nCallout';
export { default as N8nCard } from './N8nCard';
export { default as N8nDatatable } from './N8nDatatable';
export { default as N8nFormBox } from './N8nFormBox';
export { default as N8nFormInputs } from './N8nFormInputs';
export { default as N8nFormInput } from './N8nFormInput';
// export { default as N8nFormBox } from './N8nFormBox';
// export { default as N8nFormInputs } from './N8nFormInputs';
// export { default as N8nFormInput } from './N8nFormInput';
export { default as N8nHeading } from './N8nHeading';
export { default as N8nIcon } from './N8nIcon';
export { default as N8nIconButton } from './N8nIconButton';
export { default as N8nInfoAccordion } from './N8nInfoAccordion';
export { default as N8nInfoTip } from './N8nInfoTip';
export { default as N8nInput } from './N8nInput';
export { default as N8nInputLabel } from './N8nInputLabel';
export { default as N8nInputNumber } from './N8nInputNumber';
export { default as N8nLink } from './N8nLink';
export { default as N8nLoading } from './N8nLoading';
export { default as N8nMarkdown } from './N8nMarkdown';
export { default as N8nMenu } from './N8nMenu';
export { default as N8nMenuItem } from './N8nMenuItem';
export { default as N8nNodeCreatorNode } from './N8nNodeCreatorNode';
export { default as N8nNodeIcon } from './N8nNodeIcon';
export { default as N8nNotice } from './N8nNotice';
export { default as N8nOption } from './N8nOption';
// export { default as N8nInfoAccordion } from './N8nInfoAccordion';
// export { default as N8nInfoTip } from './N8nInfoTip';
// export { default as N8nInput } from './N8nInput';
// export { default as N8nInputLabel } from './N8nInputLabel';
// export { default as N8nInputNumber } from './N8nInputNumber';
// export { default as N8nLink } from './N8nLink';
// export { default as N8nLoading } from './N8nLoading';
// export { default as N8nMarkdown } from './N8nMarkdown';
// export { default as N8nMenu } from './N8nMenu';
// export { default as N8nMenuItem } from './N8nMenuItem';
// export { default as N8nNodeCreatorNode } from './N8nNodeCreatorNode';
// export { default as N8nNodeIcon } from './N8nNodeIcon';
// export { default as N8nNotice } from './N8nNotice';
// export { default as N8nOption } from './N8nOption';
export { default as N8nPopover } from './N8nPopover';
export { default as N8nPulse } from './N8nPulse';
export { default as N8nRadioButtons } from './N8nRadioButtons';
export { default as N8nSelect } from './N8nSelect';
export { default as N8nSpinner } from './N8nSpinner';
export { default as N8nSticky } from './N8nSticky';
export { default as N8nTabs } from './N8nTabs';
export { default as N8nTag } from './N8nTag';
export { default as N8nTags } from './N8nTags';
// export { default as N8nPulse } from './N8nPulse';
// export { default as N8nRadioButtons } from './N8nRadioButtons';
// export { default as N8nSelect } from './N8nSelect';
// export { default as N8nSpinner } from './N8nSpinner';
// export { default as N8nSticky } from './N8nSticky';
// export { default as N8nTabs } from './N8nTabs';
// export { default as N8nTag } from './N8nTag';
// export { default as N8nTags } from './N8nTags';
export { default as N8nText } from './N8nText';
export { default as N8nTooltip } from './N8nTooltip';
export { default as N8nTree } from './N8nTree';
export { default as N8nUserInfo } from './N8nUserInfo';
export { default as N8nUserSelect } from './N8nUserSelect';
export { default as N8nUsersList } from './N8nUsersList';
export { default as N8nResizeWrapper } from './N8nResizeWrapper';
export { default as N8nRecycleScroller } from './N8nRecycleScroller';
export { default as N8nCheckbox } from './N8nCheckbox';
export { default as N8nColorPicker } from './N8nColorPicker';
// export { default as N8nTree } from './N8nTree';
// export { default as N8nUserInfo } from './N8nUserInfo';
// export { default as N8nUserSelect } from './N8nUserSelect';
// export { default as N8nUsersList } from './N8nUsersList';
// export { default as N8nResizeWrapper } from './N8nResizeWrapper';
// export { default as N8nRecycleScroller } from './N8nRecycleScroller';
// export { default as N8nCheckbox } from './N8nCheckbox';
// export { default as N8nColorPicker } from './N8nColorPicker';

View file

@ -1,9 +1,3 @@
const hasOwnProperty = Object.prototype.hasOwnProperty;
export function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key);
}
const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
/**
* String format template
@ -12,34 +6,30 @@ const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
* https://github.com/Matt-Esch/string-template/index.js
*/
export default function () {
/**
* template
*
* @param {String | Function} string
* @param {Array} ...args
* @return {String}
*/
function template(value, ...args) {
function template(
value: string | ((...args: unknown[]) => string),
...args: Array<string | object>
) {
if (typeof value === 'function') {
return value(args);
}
const string = value;
const str = value;
if (args.length === 1 && typeof args[0] === 'object') {
args = args[0];
args = args[0] as unknown as Array<string | object>;
}
if (!args || !args.hasOwnProperty) {
args = {};
args = {} as unknown as Array<string | object>;
}
return string.replace(RE_NARGS, (match, prefix, i, index) => {
return str.replace(RE_NARGS, (match, prefix, i, index: number) => {
let result;
if (string[index - 1] === '{' && string[index + match.length] === '}') {
if (str[index - 1] === '{' && str[index + match.length] === '}') {
return i;
} else {
result = hasOwn(args, i) ? args[i] : null;
result = Object.hasOwn(args, i) ? args[i] : null;
if (result === null || result === undefined) {
return '';
}

View file

@ -1,42 +0,0 @@
import defaultLang from '../locale/lang/en';
import Format from './format';
import ElementLocale from 'element-ui/lib/locale';
import ElementLang from 'element-ui/lib/locale/lang/en';
ElementLocale.use(ElementLang);
const format = Format();
let lang = defaultLang;
let i18nHandler;
export const t = function (path, options) {
if (typeof i18nHandler === 'function') {
const value = i18nHandler.apply(this, arguments);
if (value !== null && value !== undefined && value !== path) return String(value);
}
// only support flat keys
if (lang[path] !== undefined) {
return format(lang[path], options);
}
return '';
};
export const use = function (l) {
try {
const ndsLang = require(`./lang/${l}`);
lang = ndsLang.default;
// todo breaks select empty data
// const elLang = require(`element-ui/lib/locale/lang/${l}`);;
// ElementLocale.use(elLang);
} catch (e) {}
};
export const i18n = function (fn) {
i18nHandler = fn || i18nHandler;
};
export default { use, t, i18n };

View file

@ -0,0 +1,53 @@
import defaultLang from '../locale/lang/en';
import createFormatTemplate from './format';
import type { N8nLocale, N8nLocaleTranslateFn } from '@/types';
// import { ElementLocale } from 'element-plus';
// import ElementLang from 'element-plus/lib/locale/lang/en';
//
// ElementLocale.use(ElementLang);
const format = createFormatTemplate();
let lang = defaultLang;
let i18nHandler: N8nLocaleTranslateFn;
export const t = function (
path: Parameters<typeof i18nHandler>[0],
options: Parameters<typeof i18nHandler>[1],
) {
if (typeof i18nHandler === 'function') {
const value = i18nHandler(path, options);
if (value !== null && value !== undefined && value !== path) {
return String(value);
}
}
// only support flat keys
if (lang[path] !== undefined) {
return format(lang[path], options);
}
return '';
};
export async function use(l: string) {
try {
const ndsLang = (await import(`./lang/${l}.ts`)) as { default: N8nLocale };
console.log('ndsLang', ndsLang);
lang = ndsLang.default;
// todo breaks select empty data
// const elLang = require(`element-ui/lib/locale/lang/${l}`);;
// ElementLocale.use(elLang);
} catch (e) {}
}
export const i18n = function (fn: N8nLocaleTranslateFn) {
i18nHandler = fn || i18nHandler;
};
export default { use, t, i18n };

View file

@ -1,3 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { N8nLocale } from '@/types';
export default {
'nds.auth.roles.owner': 'Owner',
'nds.userInfo.you': '(you)',
@ -8,15 +11,16 @@ export default {
'formInput.validator.fieldRequired': 'This field is required',
'formInput.validator.minCharactersRequired': 'Must be at least {minimum} characters',
'formInput.validator.maxCharactersRequired': 'Must be at most {maximum} characters',
'formInput.validator.oneNumbersRequired': (config) => {
'formInput.validator.oneNumbersRequired': (config: { minimum: number }) => {
return `Must have at least ${config.minimum} number${config.minimum > 1 ? 's' : ''}`;
},
'formInput.validator.validEmailRequired': 'Must be a valid email',
'formInput.validator.uppercaseCharsRequired': (config) =>
'formInput.validator.uppercaseCharsRequired': (config: { minimum: number }) =>
`Must have at least ${config.minimum} uppercase character${config.minimum > 1 ? 's' : ''}`,
'formInput.validator.defaultPasswordRequirements':
'8+ characters, at least 1 number and 1 capital letter',
'sticky.markdownHint': `You can style with <a href="https://docs.n8n.io/workflows/sticky-notes/" target="_blank">Markdown</a>`,
'tags.showMore': (count) => `+${count} more`,
'sticky.markdownHint':
'You can style with <a href="https://docs.n8n.io/workflows/sticky-notes/" target="_blank">Markdown</a>',
'tags.showMore': (count: number) => `+${count} more`,
'datatable.pageSize': 'Page size',
};
} as N8nLocale;

View file

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { PluginObject } from 'vue';
import type { Plugin } from 'vue';
import {
N8nActionBox,
N8nActionDropdown,
@ -9,54 +9,54 @@ import {
N8nBadge,
N8nBlockUi,
N8nButton,
N8nElButton,
// N8nElButton,
N8nCallout,
N8nCard,
N8nDatatable,
N8nFormBox,
N8nFormInputs,
N8nFormInput,
// N8nFormBox,
// N8nFormInputs,
// N8nFormInput,
N8nHeading,
N8nIcon,
N8nIconButton,
N8nInfoAccordion,
N8nInfoTip,
N8nInput,
N8nInputLabel,
N8nInputNumber,
N8nLink,
N8nLoading,
N8nMarkdown,
N8nMenu,
N8nMenuItem,
N8nNodeCreatorNode,
N8nNodeIcon,
N8nNotice,
N8nOption,
// N8nInfoAccordion,
// N8nInfoTip,
// N8nInput,
// N8nInputLabel,
// N8nInputNumber,
// N8nLink,
// N8nLoading,
// N8nMarkdown,
// N8nMenu,
// N8nMenuItem,
// N8nNodeCreatorNode,
// N8nNodeIcon,
// N8nNotice,
// N8nOption,
N8nPopover,
N8nPulse,
N8nRadioButtons,
N8nSelect,
N8nSpinner,
N8nSticky,
N8nTabs,
N8nTag,
N8nTags,
// N8nPulse,
// N8nRadioButtons,
// N8nSelect,
// N8nSpinner,
// N8nSticky,
// N8nTabs,
// N8nTag,
// N8nTags,
N8nText,
N8nTooltip,
N8nTree,
N8nUserInfo,
N8nUserSelect,
N8nUsersList,
N8nResizeWrapper,
N8nRecycleScroller,
N8nCheckbox,
N8nColorPicker,
// N8nTree,
// N8nUserInfo,
// N8nUserSelect,
// N8nUsersList,
// N8nResizeWrapper,
// N8nRecycleScroller,
// N8nCheckbox,
// N8nColorPicker,
} from './components';
export const N8nPlugin: PluginObject<{}> = {
export const N8nPlugin: Plugin<{}> = {
install: (app) => {
app.component('n8n-info-accordion', N8nInfoAccordion);
// app.component('n8n-info-accordion', N8nInfoAccordion);
app.component('n8n-action-box', N8nActionBox);
app.component('n8n-action-dropdown', N8nActionDropdown);
app.component('n8n-action-toggle', N8nActionToggle);
@ -65,47 +65,47 @@ export const N8nPlugin: PluginObject<{}> = {
app.component('n8n-badge', N8nBadge);
app.component('n8n-block-ui', N8nBlockUi);
app.component('n8n-button', N8nButton);
app.component('el-button', N8nElButton);
// app.component('el-button', N8nElButton);
app.component('n8n-callout', N8nCallout);
app.component('n8n-card', N8nCard);
app.component('n8n-datatable', N8nDatatable);
app.component('n8n-form-box', N8nFormBox);
app.component('n8n-form-inputs', N8nFormInputs);
app.component('n8n-form-input', N8nFormInput);
// app.component('n8n-form-box', N8nFormBox);
// app.component('n8n-form-inputs', N8nFormInputs);
// app.component('n8n-form-input', N8nFormInput);
app.component('n8n-heading', N8nHeading);
app.component('n8n-icon', N8nIcon);
app.component('n8n-icon-button', N8nIconButton);
app.component('n8n-info-tip', N8nInfoTip);
app.component('n8n-input', N8nInput);
app.component('n8n-input-label', N8nInputLabel);
app.component('n8n-input-number', N8nInputNumber);
app.component('n8n-loading', N8nLoading);
app.component('n8n-heading', N8nHeading);
app.component('n8n-link', N8nLink);
app.component('n8n-markdown', N8nMarkdown);
app.component('n8n-menu', N8nMenu);
app.component('n8n-menu-item', N8nMenuItem);
app.component('n8n-node-creator-node', N8nNodeCreatorNode);
app.component('n8n-node-icon', N8nNodeIcon);
app.component('n8n-notice', N8nNotice);
app.component('n8n-option', N8nOption);
// app.component('n8n-info-tip', N8nInfoTip);
// app.component('n8n-input', N8nInput);
// app.component('n8n-input-label', N8nInputLabel);
// app.component('n8n-input-number', N8nInputNumber);
// app.component('n8n-loading', N8nLoading);
// app.component('n8n-link', N8nLink);
// app.component('n8n-markdown', N8nMarkdown);
// app.component('n8n-menu', N8nMenu);
// app.component('n8n-menu-item', N8nMenuItem);
// app.component('n8n-node-creator-node', N8nNodeCreatorNode);
// app.component('n8n-node-icon', N8nNodeIcon);
// app.component('n8n-notice', N8nNotice);
// app.component('n8n-option', N8nOption);
app.component('n8n-popover', N8nPopover);
app.component('n8n-pulse', N8nPulse);
app.component('n8n-select', N8nSelect);
app.component('n8n-spinner', N8nSpinner);
app.component('n8n-sticky', N8nSticky);
app.component('n8n-radio-buttons', N8nRadioButtons);
app.component('n8n-tags', N8nTags);
app.component('n8n-tabs', N8nTabs);
app.component('n8n-tag', N8nTag);
// app.component('n8n-pulse', N8nPulse);
// app.component('n8n-select', N8nSelect);
// app.component('n8n-spinner', N8nSpinner);
// app.component('n8n-sticky', N8nSticky);
// app.component('n8n-radio-buttons', N8nRadioButtons);
// app.component('n8n-tags', N8nTags);
// app.component('n8n-tabs', N8nTabs);
// app.component('n8n-tag', N8nTag);
app.component('n8n-text', N8nText);
app.component('n8n-tooltip', N8nTooltip);
app.component('n8n-user-info', N8nUserInfo);
app.component('n8n-tree', N8nTree);
app.component('n8n-users-list', N8nUsersList);
app.component('n8n-user-select', N8nUserSelect);
app.component('n8n-resize-wrapper', N8nResizeWrapper);
app.component('n8n-recycle-scroller', N8nRecycleScroller);
app.component('n8n-checkbox', N8nCheckbox);
app.component('n8n-color-picker', N8nColorPicker);
// app.component('n8n-user-info', N8nUserInfo);
// app.component('n8n-tree', N8nTree);
// app.component('n8n-users-list', N8nUsersList);
// app.component('n8n-user-select', N8nUserSelect);
// app.component('n8n-resize-wrapper', N8nResizeWrapper);
// app.component('n8n-recycle-scroller', N8nRecycleScroller);
// app.component('n8n-checkbox', N8nCheckbox);
// app.component('n8n-color-picker', N8nColorPicker);
},
};

View file

@ -1 +0,0 @@
declare module 'vue2-boring-avatars';

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
export default {
title: 'Utilities/Lists',

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue';
import type { StoryFn } from '@storybook/vue3';
import SpacingPreview from '../components/SpacingPreview.vue';
export default {
@ -6,11 +6,12 @@ export default {
};
const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
SpacingPreview,
},
template: '<spacing-preview v-bind="$props" />',
template: '<spacing-preview v-bind="args" />',
});
export const Padding = Template.bind({});

View file

@ -0,0 +1,3 @@
export type N8nLocaleTranslateFn = (path: string, options: object) => string;
export type N8nLocale = Record<string, string | ((...args: unknown[]) => string)>;

View file

@ -1,6 +1,7 @@
export * from './button';
export * from './datatable';
export * from './form';
export * from './i18n';
export * from './menu';
export * from './router';
export * from './user';

View file

@ -1,4 +1,4 @@
import vue from '@vitejs/plugin-vue2';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import { defineConfig, mergeConfig } from 'vite';
import { defineConfig as defineVitestConfig } from 'vitest/config';
@ -11,7 +11,6 @@ export default mergeConfig(
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'vue2-boring-avatars': require.resolve('vue2-boring-avatars'),
},
},
build: {

View file

@ -40,7 +40,7 @@
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-regular-svg-icons": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.10",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@jsplumb/browser-ui": "^5.13.2",
"@jsplumb/common": "^5.13.2",
"@jsplumb/connector-bezier": "^5.13.2",
@ -68,12 +68,12 @@
"timeago.js": "^4.0.2",
"uuid": "^8.3.2",
"v-click-outside": "^3.1.2",
"vue": "^2.7.14",
"vue": "^3.3.4",
"vue-agile": "^2.0.0",
"vue-i18n": "^8.26.7",
"vue-i18n": "^9.2.2",
"vue-infinite-loading": "^2.4.5",
"vue-json-pretty": "1.9.3",
"vue-router": "^3.6.5",
"vue-router": "^4.2.2",
"vue2-teleport": "^1.0.1",
"vue2-touch-events": "^3.2.1",
"xss": "^1.0.14"
@ -84,7 +84,7 @@
"@sentry/vite-plugin": "^0.4.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/user-event": "^14.4.3",
"@testing-library/vue": "^5.8.3",
"@testing-library/vue": "^6.6.1",
"@types/canvas-confetti": "^1.6.0",
"@types/dateformat": "^3.0.0",
"@types/file-saver": "^2.0.1",
@ -93,6 +93,7 @@
"@types/lodash-es": "^4.17.6",
"@types/luxon": "^3.2.0",
"@types/uuid": "^8.3.2",
"@vitejs/plugin-vue": "^4.2.3",
"miragejs": "^0.1.47"
}
}

View file

@ -1,5 +1,5 @@
import Vue from 'vue';
import type { PluginObject } from 'vue';
import type { Plugin } from 'vue';
import axios from 'axios';
import VueI18n from 'vue-i18n';
import type { INodeTranslationHeaders } from '@/Interface';
@ -500,13 +500,13 @@ export class I18nClass {
const loadedLanguages = ['en'];
function setLanguage(language: string) {
async function setLanguage(language: string) {
i18nInstance.locale = language;
axios.defaults.headers.common['Accept-Language'] = language;
document!.querySelector('html')!.setAttribute('lang', language);
// update n8n design system and element ui
locale.use(language);
await locale.use(language);
return language;
}
@ -599,9 +599,9 @@ export function addHeaders(headers: INodeTranslationHeaders, language: string) {
export const i18n: I18nClass = new I18nClass();
export const I18nPlugin: PluginObject<{}> = {
install(app): void {
locale.use('en');
export const I18nPlugin: Plugin<{}> = {
async install(app) {
await locale.use('en');
locale.i18n((key: string, options?: { interpolate: object }) =>
i18nInstance.t(key, options && options.interpolate),
);

View file

@ -1,5 +1,5 @@
import vue from '@vitejs/plugin-vue2';
import path, { resolve } from 'path';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import { defineConfig, mergeConfig } from 'vite';
import { defineConfig as defineVitestConfig } from 'vitest/config';
import { sentryVitePlugin } from '@sentry/vite-plugin';
@ -63,7 +63,7 @@ const alias = [
},
{
find: /element-ui\/(packages|lib)\/button$/,
replacement: path.resolve(
replacement: resolve(
__dirname,
'..',
'design-system/src/components/N8nButton/overrides/ElButton.ts',

View file

@ -1,262 +0,0 @@
diff --git a/lib/element-ui.common.js b/lib/element-ui.common.js
index 6209b8b7f21c6eea447dd4671b7c4cfc1ef5e9c2..a26772af8dcdcbc0e3a6058bda30c7f9f143cd5d 100644
--- a/lib/element-ui.common.js
+++ b/lib/element-ui.common.js
@@ -21471,14 +21471,8 @@ mainvue_type_template_id_52060272_render._withStripped = true
popper.setAttribute('tabindex', 0);
if (this.trigger !== 'click') {
- Object(dom_["on"])(reference, 'focusin', function () {
- _this.handleFocus();
- var instance = reference.__vue__;
- if (instance && typeof instance.focus === 'function') {
- instance.focus();
- }
- });
- Object(dom_["on"])(popper, 'focusin', this.handleFocus);
+ Object(dom_["on"])(reference, 'focusin', this.handleRefrenceFocus);
+ Object(dom_["on"])(popper, 'focusin', this.handlePopperFocus);
Object(dom_["on"])(reference, 'focusout', this.handleBlur);
Object(dom_["on"])(popper, 'focusout', this.handleBlur);
}
@@ -21524,7 +21518,17 @@ mainvue_type_template_id_52060272_render._withStripped = true
doClose: function doClose() {
this.showPopper = false;
},
- handleFocus: function handleFocus() {
+ handleRefrenceFocus: function handleRefrenceFocus() {
+ this.handlePopperFocus();
+ if (!this.referenceElm) {
+ return;
+ }
+ const instance = this.referenceElm.__vue__;
+ if (instance && typeof instance.focus === 'function') {
+ instance.focus();
+ }
+ },
+ handlePopperFocus: function handlePopperFocus() {
Object(dom_["addClass"])(this.referenceElm, 'focusing');
if (this.trigger === 'click' || this.trigger === 'focus') this.showPopper = true;
},
@@ -21570,7 +21574,7 @@ mainvue_type_template_id_52060272_render._withStripped = true
var popper = this.popper || this.$refs.popper;
if (!reference && this.$refs.wrapper.children) {
- reference = this.referenceElm = this.$refs.wrapper.children[0];
+ reference = this.$refs.wrapper.children[0];
}
if (!this.$el || !reference || this.$el.contains(e.target) || reference.contains(e.target) || !popper || popper.contains(e.target)) return;
this.showPopper = false;
@@ -21590,18 +21594,28 @@ mainvue_type_template_id_52060272_render._withStripped = true
},
destroyed: function destroyed() {
- var reference = this.reference;
+ var reference = this.referenceElm;
+ var popper = this.popper || this.$refs.popper;
+ Object(dom_["off"])(reference, 'focusin', this.handleRefrenceFocus);
+ Object(dom_["off"])(popper, 'focusin', this.handlePopperFocus);
+ Object(dom_["off"])(reference, 'focusout', this.handleBlur);
+ Object(dom_["off"])(popper, 'focusout', this.handleBlur);
+ Object(dom_["off"])(reference, 'keydown', this.handleKeydown);
+ Object(dom_["off"])(reference, 'click', this.handleClick);
Object(dom_["off"])(reference, 'click', this.doToggle);
+ Object(dom_["off"])(document, 'click', this.handleDocumentClick);
+ Object(dom_["off"])(reference, 'mouseenter', this.handleMouseEnter);
+ Object(dom_["off"])(popper, 'mouseenter', this.handleMouseEnter);
+ Object(dom_["off"])(reference, 'mouseleave', this.handleMouseLeave);
+ Object(dom_["off"])(popper, 'mouseleave', this.handleMouseLeave);
Object(dom_["off"])(reference, 'mouseup', this.doClose);
Object(dom_["off"])(reference, 'mousedown', this.doShow);
Object(dom_["off"])(reference, 'focusin', this.doShow);
Object(dom_["off"])(reference, 'focusout', this.doClose);
Object(dom_["off"])(reference, 'mousedown', this.doShow);
Object(dom_["off"])(reference, 'mouseup', this.doClose);
- Object(dom_["off"])(reference, 'mouseleave', this.handleMouseLeave);
- Object(dom_["off"])(reference, 'mouseenter', this.handleMouseEnter);
- Object(dom_["off"])(document, 'click', this.handleDocumentClick);
+ this.referenceElm = undefined;
}
});
// CONCATENATED MODULE: ./packages/popover/src/main.vue?vue&type=script&lang=js&
@@ -21805,18 +21819,7 @@ main.directive = directive;
this.$el.setAttribute('tabindex', this.tabindex);
Object(dom_["on"])(this.referenceElm, 'mouseenter', this.show);
Object(dom_["on"])(this.referenceElm, 'mouseleave', this.hide);
- Object(dom_["on"])(this.referenceElm, 'focus', function () {
- if (!_this3.$slots.default || !_this3.$slots.default.length) {
- _this3.handleFocus();
- return;
- }
- var instance = _this3.$slots.default[0].componentInstance;
- if (instance && instance.focus) {
- instance.focus();
- } else {
- _this3.handleFocus();
- }
- });
+ Object(dom_["on"])(this.referenceElm, 'focus', this.handleFocus);
Object(dom_["on"])(this.referenceElm, 'blur', this.handleBlur);
Object(dom_["on"])(this.referenceElm, 'click', this.removeFocusing);
}
@@ -21849,8 +21852,18 @@ main.directive = directive;
this.debounceClose();
},
handleFocus: function handleFocus() {
- this.focusing = true;
- this.show();
+ if (!this.$slots.default || !this.$slots.default.length) {
+ this.focusing = true;
+ this.show();
+ return;
+ }
+ var instance = this.$slots.default[0].componentInstance;
+ if (instance && instance.focus) {
+ instance.focus();
+ } else {
+ this.focusing = true;
+ this.show();
+ }
},
handleBlur: function handleBlur() {
this.focusing = false;
@@ -21918,6 +21931,7 @@ main.directive = directive;
this.popperVM && this.popperVM.$destroy();
},
destroyed: function destroyed() {
+ this.popperVM && this.popperVM.$destroy();
var reference = this.referenceElm;
if (reference.nodeType === 1) {
Object(dom_["off"])(reference, 'mouseenter', this.show);
diff --git a/packages/popover/src/main.vue b/packages/popover/src/main.vue
index ab5d060182c2e671989f1aba190c85a074d2c754..8b464ad39a78ac6efead5f687d977500642e45dc 100644
--- a/packages/popover/src/main.vue
+++ b/packages/popover/src/main.vue
@@ -98,16 +98,9 @@ export default {
reference.setAttribute('aria-describedby', this.tooltipId);
reference.setAttribute('tabindex', this.tabindex); // tab序列
popper.setAttribute('tabindex', 0);
-
if (this.trigger !== 'click') {
- on(reference, 'focusin', () => {
- this.handleFocus();
- const instance = reference.__vue__;
- if (instance && typeof instance.focus === 'function') {
- instance.focus();
- }
- });
- on(popper, 'focusin', this.handleFocus);
+ on(reference, 'focusin', this.handleRefrenceFocus);
+ on(popper, 'focusin', this.handlePopperFocus);
on(reference, 'focusout', this.handleBlur);
on(popper, 'focusout', this.handleBlur);
}
@@ -154,7 +147,17 @@ export default {
doClose() {
this.showPopper = false;
},
- handleFocus() {
+ handleRefrenceFocus() {
+ this.handlePopperFocus();
+ if (!this.referenceElm) {
+ return;
+ }
+ const instance = this.referenceElm.__vue__;
+ if (instance && typeof instance.focus === 'function') {
+ instance.focus();
+ }
+ },
+ handlePopperFocus() {
addClass(this.referenceElm, 'focusing');
if (this.trigger === 'click' || this.trigger === 'focus') this.showPopper = true;
},
@@ -193,9 +196,8 @@ export default {
handleDocumentClick(e) {
let reference = this.reference || this.$refs.reference;
const popper = this.popper || this.$refs.popper;
-
if (!reference && this.$refs.wrapper.children) {
- reference = this.referenceElm = this.$refs.wrapper.children[0];
+ reference = this.$refs.wrapper.children[0];
}
if (!this.$el ||
!reference ||
@@ -218,20 +220,26 @@ export default {
}
}
},
-
destroyed() {
- const reference = this.reference;
-
+ const reference = this.referenceElm;
+ const popper = this.popper || this.$refs.popper;
+ off(reference, 'focusin', this.handleRefrenceFocus);
+ off(popper, 'focusin', this.handlePopperFocus);
+ off(reference, 'focusout', this.handleBlur);
+ off(popper, 'focusout', this.handleBlur);
+ off(reference, 'keydown', this.handleKeydown);
+ off(reference, 'click', this.handleClick);
off(reference, 'click', this.doToggle);
- off(reference, 'mouseup', this.doClose);
- off(reference, 'mousedown', this.doShow);
+ off(document, 'click', this.handleDocumentClick);
+ off(reference, 'mouseenter', this.handleMouseEnter);
+ off(popper, 'mouseenter', this.handleMouseEnter);
+ off(reference, 'mouseleave', this.handleMouseLeave);
+ off(popper, 'mouseleave', this.handleMouseLeave);
off(reference, 'focusin', this.doShow);
off(reference, 'focusout', this.doClose);
off(reference, 'mousedown', this.doShow);
off(reference, 'mouseup', this.doClose);
- off(reference, 'mouseleave', this.handleMouseLeave);
- off(reference, 'mouseenter', this.handleMouseEnter);
- off(document, 'click', this.handleDocumentClick);
+ this.referenceElm = undefined;
}
};
</script>
diff --git a/packages/tooltip/src/main.js b/packages/tooltip/src/main.js
index dc930ec58d42328a4d62cddb22fd513db31793cf..d9a6afc80d27ea89b838a47f395e249131c1370c 100644
--- a/packages/tooltip/src/main.js
+++ b/packages/tooltip/src/main.js
@@ -113,18 +113,7 @@ export default {
this.$el.setAttribute('tabindex', this.tabindex);
on(this.referenceElm, 'mouseenter', this.show);
on(this.referenceElm, 'mouseleave', this.hide);
- on(this.referenceElm, 'focus', () => {
- if (!this.$slots.default || !this.$slots.default.length) {
- this.handleFocus();
- return;
- }
- const instance = this.$slots.default[0].componentInstance;
- if (instance && instance.focus) {
- instance.focus();
- } else {
- this.handleFocus();
- }
- });
+ on(this.referenceElm, 'focus', this.handleFocus);
on(this.referenceElm, 'blur', this.handleBlur);
on(this.referenceElm, 'click', this.removeFocusing);
}
@@ -157,6 +146,18 @@ export default {
this.debounceClose();
},
handleFocus() {
+ if (!this.$slots.default || !this.$slots.default.length) {
+ this.doFocus();
+ return;
+ }
+ const instance = this.$slots.default[0].componentInstance;
+ if (instance && instance.focus) {
+ instance.focus();
+ } else {
+ this.doFocus();
+ }
+ },
+ doFocus() {
this.focusing = true;
this.show();
},

File diff suppressed because it is too large Load diff