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" "qqjs>globby": "^11.1.0"
}, },
"patchedDependencies": { "patchedDependencies": {
"element-ui@2.15.12": "patches/element-ui@2.15.12.patch",
"typedi@0.10.0": "patches/typedi@0.10.0.patch", "typedi@0.10.0": "patches/typedi@0.10.0.patch",
"@sentry/cli@2.17.0": "patches/@sentry__cli@2.17.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 = { module.exports = {
framework: { stories: [
name: '@storybook/vue-webpack5', '../src/styleguide/*.stories.@(js|jsx|ts|tsx)',
options: {}, '../src/components/N8nActionBox/*.stories.@(js|jsx|ts|tsx)',
}, '../src/components/N8nActionDropdown/*.stories.@(js|jsx|ts|tsx)',
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.{ts,js}'], '../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: [ addons: [
'@storybook/addon-styling',
'@storybook/addon-links', '@storybook/addon-links',
'@storybook/addon-essentials', '@storybook/addon-essentials',
{ // Disabled until this is actually used rather otherwise its a blank tab
name: '@storybook/addon-postcss', // '@storybook/addon-interactions',
options: { '@storybook/addon-a11y',
postcssLoaderOptions: { 'storybook-dark-mode',
implementation: require('postcss'),
},
},
},
'storybook-addon-themes',
], ],
webpackFinal: async (config) => { staticDirs: ['../public'],
config.module.rules.push({ framework: {
test: /\.scss$/, name: '@storybook/vue3-vite',
oneOf: [ options: {},
{ },
resourceQuery: /module/, disableTelemetry: true,
use: [ async viteFinal(config, { configType }) {
'vue-style-loader', // return the customized config
{ return mergeConfig(config, {
loader: 'css-loader', // customize the Vite config here
options: { resolve: {
modules: { alias: [
localIdentName: '[path][name]__[local]--[hash:base64:5]', {
}, find: /^@n8n-design-system\//,
}, replacement: `${resolve(__dirname, '..')}/src/`,
}, },
'sass-loader', ],
], },
include: path.resolve(__dirname, '../'), define: { 'process.env': {} },
},
{
use: ['vue-style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
},
],
}); });
},
config.resolve.alias = { docs: {
...config.resolve.alias, autodocs: true,
'@/': path.resolve(__dirname, '../src/'),
};
return config;
}, },
}; };

View file

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

View file

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

View file

@ -40,37 +40,43 @@
"devDependencies": { "devDependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/vue-fontawesome": "^2.0.9", "@fortawesome/vue-fontawesome": "^3.0.3",
"@storybook/addon-actions": "^7.0.7", "@storybook/addon-a11y": "^7.0.21",
"@storybook/addon-docs": "^7.0.7", "@storybook/addon-actions": "^7.0.21",
"@storybook/addon-essentials": "^7.0.7", "@storybook/addon-docs": "^7.0.21",
"@storybook/addon-links": "^7.0.7", "@storybook/addon-essentials": "^7.0.21",
"@storybook/addon-postcss": "^3.0.0-alpha.1", "@storybook/addon-links": "^7.0.21",
"@storybook/vue": "^7.0.7", "@storybook/addon-postcss": "3.0.0-alpha.1",
"@storybook/vue-webpack5": "^7.0.7", "@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/jest-dom": "^5.16.5",
"@testing-library/user-event": "^14.4.3", "@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": "^12.2.3",
"@types/markdown-it-emoji": "^2.0.2", "@types/markdown-it-emoji": "^2.0.2",
"@types/markdown-it-link-attributes": "^3.0.1", "@types/markdown-it-link-attributes": "^3.0.1",
"@types/sanitize-html": "^2.8.0", "@types/sanitize-html": "^2.9.0",
"autoprefixer": "^10.4.13", "@vitejs/plugin-vue": "^4.2.3",
"core-js": "^3.27.2", "autoprefixer": "^10.4.14",
"core-js": "^3.31.0",
"jsdom": "21.1.0", "jsdom": "21.1.0",
"sass": "^1.58.0", "sass": "^1.63.4",
"sass-loader": "^13.2.0", "sass-loader": "^13.3.2",
"storybook": "^7.0.7", "storybook": "^7.0.21",
"storybook-addon-themes": "^6.1.0" "storybook-addon-themes": "^6.1.0",
"storybook-dark-mode": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"element-ui": "~2.15.12", "element-plus": "^2.3.6",
"element-ui": "~2.15.13",
"markdown-it": "^13.0.1", "markdown-it": "^13.0.1",
"markdown-it-emoji": "^2.0.2", "markdown-it-emoji": "^2.0.2",
"markdown-it-link-attributes": "^4.0.1", "markdown-it-link-attributes": "^4.0.1",
"markdown-it-task-lists": "^2.1.1", "markdown-it-task-lists": "^2.1.1",
"sanitize-html": "2.10.0", "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", "vue2-boring-avatars": "^0.3.8",
"xss": "^1.0.14" "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 N8nActionBox from './ActionBox.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/ActionBox', title: 'Atoms/ActionBox',
@ -9,8 +9,8 @@ export default {
calloutTheme: { calloutTheme: {
control: { control: {
type: 'select', type: 'select',
options: ['info', 'success', 'warning', 'danger', 'custom'],
}, },
options: ['info', 'success', 'warning', 'danger', 'custom'],
}, },
}, },
parameters: { parameters: {
@ -23,11 +23,12 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nActionBox, N8nActionBox,
}, },
template: '<n8n-action-box v-bind="$props" @click="onClick" />', template: '<n8n-action-box v-bind="args" @click="onClick" />',
methods, methods,
}); });

View file

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

View file

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

View file

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

View file

@ -42,11 +42,7 @@
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus';
Dropdown as ElDropdown,
DropdownMenu as ElDropdownMenu,
DropdownItem as ElDropdownItem,
} from 'element-ui';
import N8nIcon from '../N8nIcon'; import N8nIcon from '../N8nIcon';
import type { UserAction } from '@/types'; 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 N8nAlert from './Alert.vue';
import N8nIcon from '../N8nIcon'; import N8nIcon from '../N8nIcon';
@ -18,12 +18,13 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nAlert, N8nAlert,
}, },
template: 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({}); export const ContentAsProps = Template.bind({});
@ -38,13 +39,14 @@ ContentAsProps.args = {
}; };
const TemplateForSlots: StoryFn = (args, { argTypes }) => ({ const TemplateForSlots: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nAlert, N8nAlert,
N8nIcon, N8nIcon,
}, },
template: `<div style="position: relative; width: 100%; height: 300px;"> template: `<div style="position: relative; width: 100%; height: 300px;">
<n8n-alert v-bind="$props"> <n8n-alert v-bind="args">
<template #title>Title</template> <template #title>Title</template>
<template>Description</template> <template>Description</template>
<template #aside><button>Button</button></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'; import N8nAvatar from './Avatar.vue';
export default { export default {
@ -13,14 +13,16 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nAvatar, N8nAvatar,
}, },
template: '<n8n-avatar v-bind="$props" />', template: '<n8n-avatar v-bind="args" />',
}); });
export const Avatar = Template.bind({}); export const Avatar = Template.bind({});
Avatar.args = { Avatar.args = {
name: 'Sunny Side', firstName: 'Sunny',
lastName: 'Side',
}; };

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,5 @@
import N8nCheckbox from './Checkbox.vue'; import N8nCheckbox from './Checkbox.vue';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
export default { export default {
@ -21,7 +21,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
data: () => ({ data: () => ({
isChecked: false, 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, methods,
}); });

View file

@ -1,5 +1,5 @@
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import N8nColorPicker from './ColorPicker.vue'; import N8nColorPicker from './ColorPicker.vue';
export default { export default {
@ -44,7 +44,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
color: null, color: null,
}), }),
template: 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, methods,
}); });

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
import N8nFormInput from './FormInput.vue'; import N8nFormInput from './FormInput.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Modules/FormInput', title: 'Modules/FormInput',
@ -15,12 +15,13 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nFormInput, N8nFormInput,
}, },
template: ` 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, methods,
data() { data() {

View file

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

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import N8nHeading from './Heading.vue'; import N8nHeading from './Heading.vue';
export default { export default {
@ -8,24 +8,25 @@ export default {
size: { size: {
control: { control: {
type: 'select', type: 'select',
options: ['2xlarge', 'xlarge', 'large', 'medium', 'small'],
}, },
options: ['2xlarge', 'xlarge', 'large', 'medium', 'small'],
}, },
color: { color: {
control: { control: {
type: 'select', 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 }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nHeading, 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({}); export const Heading = Template.bind({});

View file

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

View file

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

View file

@ -1,5 +1,5 @@
<template> <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]" /> <font-awesome-icon :icon="icon" :spin="spin" :class="$style[size]" />
</n8n-text> </n8n-text>
</template> </template>

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import N8nInfoTip from './InfoTip.vue'; import N8nInfoTip from './InfoTip.vue';
export default { export default {
@ -7,12 +7,13 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nInfoTip, N8nInfoTip,
}, },
template: 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({}); export const Note = Template.bind({});

View file

@ -1,7 +1,7 @@
import N8nInput from './Input.vue'; import N8nInput from './Input.vue';
import N8nIcon from '../N8nIcon'; import N8nIcon from '../N8nIcon';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Input', title: 'Atoms/Input',
@ -36,12 +36,13 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nInput, N8nInput,
}, },
template: 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() { data() {
return { return {
val: '', val: '',
@ -61,7 +62,7 @@ const ManyTemplate: StoryFn = (args, { argTypes }) => ({
N8nInput, N8nInput,
}, },
template: 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, methods,
data() { data() {
return { return {
@ -89,7 +90,7 @@ const WithPrefix: StoryFn = (args, { argTypes }) => ({
N8nInput, N8nInput,
}, },
template: 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() { data() {
return { return {
val: '', val: '',
@ -110,7 +111,7 @@ const WithSuffix: StoryFn = (args, { argTypes }) => ({
N8nInput, N8nInput,
}, },
template: 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() { data() {
return { return {
val: '', val: '',

View file

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

View file

@ -1,6 +1,6 @@
import N8nInputLabel from './InputLabel.vue'; import N8nInputLabel from './InputLabel.vue';
import N8nInput from '../N8nInput'; import N8nInput from '../N8nInput';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Input Label', title: 'Atoms/Input Label',
@ -12,13 +12,14 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nInputLabel, N8nInputLabel,
N8nInput, N8nInput,
}, },
template: 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({}); export const InputLabel = Template.bind({});

View file

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

View file

@ -1,6 +1,6 @@
import N8nInputNumber from './InputNumber.vue'; import N8nInputNumber from './InputNumber.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Input Number', title: 'Atoms/Input Number',
@ -53,11 +53,12 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nInputNumber, 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() { data() {
return { return {
val: null, val: null,
@ -78,7 +79,7 @@ const ManyTemplate: StoryFn = (args, { argTypes }) => ({
N8nInputNumber, N8nInputNumber,
}, },
template: 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, methods,
data() { data() {
return { return {

View file

@ -1,6 +1,6 @@
import N8nLink from './Link.vue'; import N8nLink from './Link.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Link', title: 'Atoms/Link',
@ -9,8 +9,8 @@ export default {
size: { size: {
control: { control: {
type: 'select', type: 'select',
options: ['small', 'medium', 'large'],
}, },
options: ['small', 'medium', 'large'],
}, },
}, },
}; };
@ -20,11 +20,12 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nLink, 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, methods,
}); });

View file

@ -1,5 +1,5 @@
<template> <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}`]"> <span :class="$style[`${underline ? `${theme}-underline` : theme}`]">
<n8n-text :size="size" :bold="bold"> <n8n-text :size="size" :bold="bold">
<slot></slot> <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'; import N8nLoading from './Loading.vue';
export default { export default {
@ -18,24 +18,25 @@ export default {
rows: { rows: {
control: { control: {
type: 'select', type: 'select',
options: [1, 2, 3, 4, 5],
}, },
options: [1, 2, 3, 4, 5],
}, },
variant: { variant: {
control: { control: {
type: 'select', type: 'select',
options: ['button', 'h1', 'image', 'p'],
}, },
options: ['button', 'h1', 'image', 'p'],
}, },
}, },
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nLoading, N8nLoading,
}, },
template: '<n8n-loading v-bind="$props"></n8n-loading>', template: '<n8n-loading v-bind="args"></n8n-loading>',
}); });
export const Loading = Template.bind({}); 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'; import N8nMarkdown from './Markdown.vue';
export default { export default {
@ -18,24 +18,25 @@ export default {
loadingBlocks: { loadingBlocks: {
control: { control: {
type: 'select', type: 'select',
options: [1, 2, 3, 4, 5],
}, },
options: [1, 2, 3, 4, 5],
}, },
loadingRows: { loadingRows: {
control: { control: {
type: 'select', type: 'select',
options: [1, 2, 3, 4, 5],
}, },
options: [1, 2, 3, 4, 5],
}, },
}, },
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nMarkdown, N8nMarkdown,
}, },
template: '<n8n-markdown v-bind="$props"></n8n-markdown>', template: '<n8n-markdown v-bind="args"></n8n-markdown>',
}); });
export const Markdown = Template.bind({}); export const Markdown = Template.bind({});

View file

@ -1,7 +1,7 @@
import N8nMenu from './Menu.vue'; import N8nMenu from './Menu.vue';
import N8nIcon from '../N8nIcon'; import N8nIcon from '../N8nIcon';
import N8nText from '../N8nText'; import N8nText from '../N8nText';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
export default { export default {
@ -15,19 +15,21 @@ const methods = {
}; };
const template: StoryFn = (args, { argTypes }) => ({ const template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nMenu, N8nMenu,
}, },
template: ` template: `
<div style="height: 90vh; width: 200px"> <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> </div>
`, `,
methods, methods,
}); });
const templateWithHeaderAndFooter: StoryFn = (args, { argTypes }) => ({ const templateWithHeaderAndFooter: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nMenu, N8nMenu,
@ -36,7 +38,7 @@ const templateWithHeaderAndFooter: StoryFn = (args, { argTypes }) => ({
}, },
template: ` template: `
<div style="height: 90vh; width: 200px"> <div style="height: 90vh; width: 200px">
<n8n-menu v-bind="$props" @select="onSelect"> <n8n-menu v-bind="args" @select="onSelect">
<template #header> <template #header>
<a href="#" class="p-m hideme" style="display: block;"> <a href="#" class="p-m hideme" style="display: block;">
<n8n-icon icon="long-arrow-alt-left"/>&nbsp;&nbsp;Back to home <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 }) => ({ const templateWithAllSlots: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nMenu, N8nMenu,
@ -63,7 +66,7 @@ const templateWithAllSlots: StoryFn = (args, { argTypes }) => ({
}, },
template: ` template: `
<div style="height: 90vh; width: 200px"> <div style="height: 90vh; width: 200px">
<n8n-menu v-bind="$props" @select="onSelect"> <n8n-menu v-bind="args" @select="onSelect">
<template #header> <template #header>
<a href="#" class="p-m hideme" style="display: block;"> <a href="#" class="p-m hideme" style="display: block;">
<n8n-icon icon="long-arrow-alt-left"/>&nbsp;&nbsp;Back to home <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"> <div v-if="$slots.menuPrefix" :class="$style.menuPrefix">
<slot name="menuPrefix"></slot> <slot name="menuPrefix"></slot>
</div> </div>
<el-menu :defaultActive="defaultActive" :collapse="collapsed" v-on="$listeners"> <el-menu :defaultActive="defaultActive" :collapse="collapsed" v-bind="$attrs">
<n8n-menu-item <n8n-menu-item
v-for="item in upperMenuItems" v-for="item in upperMenuItems"
:key="item.id" :key="item.id"
@ -29,7 +29,7 @@
</div> </div>
<div :class="[$style.lowerContent, 'pb-2xs']"> <div :class="[$style.lowerContent, 'pb-2xs']">
<slot name="beforeLowerMenu"></slot> <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 <n8n-menu-item
v-for="item in lowerMenuItems" v-for="item in lowerMenuItems"
:key="item.id" :key="item.id"

View file

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

View file

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

View file

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

View file

@ -1,5 +1,5 @@
import N8nNodeIcon from './NodeIcon.vue'; import N8nNodeIcon from './NodeIcon.vue';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/NodeIcon', title: 'Atoms/NodeIcon',
@ -11,7 +11,7 @@ const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
components: { components: {
N8nNodeIcon, 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({}); export const FileIcon = DefaultTemplate.bind({});

View file

@ -7,7 +7,7 @@
[$style.disabled]: disabled, [$style.disabled]: disabled,
}" }"
:style="iconStyleData" :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 --> <!-- 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"> <n8n-tooltip placement="top" :disabled="!showTooltip" v-if="showTooltip">

View file

@ -1,5 +1,5 @@
import N8nNotice from './Notice.vue'; import N8nNotice from './Notice.vue';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Notice', title: 'Atoms/Notice',
@ -18,7 +18,7 @@ const SlotTemplate: StoryFn = (args, { argTypes }) => ({
N8nNotice, N8nNotice,
}, },
template: 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 }) => ({ const PropTemplate: StoryFn = (args, { argTypes }) => ({
@ -26,7 +26,7 @@ const PropTemplate: StoryFn = (args, { argTypes }) => ({
components: { components: {
N8nNotice, N8nNotice,
}, },
template: '<n8n-notice v-bind="$props"/>', template: '<n8n-notice v-bind="args"/>',
}); });
export const Warning = SlotTemplate.bind({}); export const Warning = SlotTemplate.bind({});

View file

@ -1,4 +1,17 @@
<script lang="ts"> <script lang="ts">
import { Option } from 'element-ui'; import { ElOption } from 'element-plus';
export default Option; import { defineComponent } from 'vue';
export default defineComponent({
props: {
...ElOption.props,
},
components: {
ElOption,
},
});
</script> </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'; import N8nPagination from './Pagination.vue';
export default { export default {
@ -7,11 +7,12 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nPagination, N8nPagination,
}, },
template: '<n8n-pagination v-bind="$props" />', template: '<n8n-pagination v-bind="args" />',
}); });
export const Pagination: StoryFn = Template.bind({}); export const Pagination: StoryFn = Template.bind({});

View file

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

View file

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

View file

@ -1,4 +1,23 @@
<script lang="ts"> <script lang="ts">
import { Popover } from 'element-ui'; import { ElPopover } from 'element-plus';
export default Popover; import { defineComponent } from 'vue';
export default defineComponent({
name: 'N8nPopover',
props: {
...ElPopover.props,
},
components: {
ElPopover,
},
});
</script> </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 N8nPulse from './Pulse.vue';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Pulse', title: 'Atoms/Pulse',

View file

@ -1,7 +1,7 @@
import N8nRadioButtons from './RadioButtons.vue'; import N8nRadioButtons from './RadioButtons.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/RadioButtons', title: 'Atoms/RadioButtons',
@ -22,11 +22,12 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nRadioButtons, 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>`, </n8n-radio-buttons>`,
methods, methods,
data() { 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 */ /* 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 N8nRecycleScroller from './RecycleScroller.vue';
import type { ComponentInstance } from 'vue'; import type { ComponentInstance } from 'vue';
@ -42,7 +42,7 @@ const Template: StoryFn = () => ({
}, },
}, },
template: `<div style="height: calc(100vh - 30px); width: 100%; overflow: auto"> 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 }"> <template #default="{ item, updateItemSize }">
<div <div
:ref="'item-' + item.id" :ref="'item-' + item.id"

View file

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

View file

@ -1,9 +1,9 @@
<template> <template>
<span> <span>
<router-link v-if="useRouterLink" :to="to" v-on="$listeners"> <router-link v-if="useRouterLink" :to="to" v-bind="$attrs">
<slot></slot> <slot></slot>
</router-link> </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> <slot></slot>
</a> </a>
</span> </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 N8nSelect from './Select.vue';
import N8nOption from '../N8nOption'; import N8nOption from '../N8nOption';
import N8nIcon from '../N8nIcon'; import N8nIcon from '../N8nIcon';
@ -16,8 +16,8 @@ export default {
size: { size: {
control: { control: {
type: 'select', type: 'select',
options: ['large', 'medium', 'small', 'mini'],
}, },
options: ['large', 'medium', 'small', 'mini'],
}, },
loading: { loading: {
control: { control: {
@ -46,6 +46,7 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nSelect, N8nSelect,
@ -53,7 +54,7 @@ const Template: StoryFn = (args, { argTypes }) => ({
N8nIcon, N8nIcon,
}, },
template: 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() { data() {
return { return {
val: '', val: '',
@ -73,7 +74,7 @@ Filterable.args = {
const selects = ['large', 'medium', 'small', 'mini'] const selects = ['large', 'medium', 'small', 'mini']
.map( .map(
(size) => (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(''); .join('');
@ -103,7 +104,7 @@ Sizes.args = {
const selectsWithIcon = ['xlarge', 'large', 'medium', 'small', 'mini'] const selectsWithIcon = ['xlarge', 'large', 'medium', 'small', 'mini']
.map( .map(
(size) => (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(''); .join('');
@ -138,7 +139,7 @@ const LimitedWidthTemplate: StoryFn = (args, { argTypes }) => ({
N8nIcon, N8nIcon,
}, },
template: 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() { data() {
return { return {
val: '', val: '',

View file

@ -10,12 +10,11 @@
<slot name="prepend" /> <slot name="prepend" />
</div> </div>
<el-select <el-select
v-bind="$props" v-bind="{ ...$props, ...$attrs }"
:value="value" :modelValue="modelValue"
:size="computedSize" :size="computedSize"
:class="$style[classes]" :class="$style[classes]"
:popper-class="popperClass" :popper-class="popperClass"
v-on="$listeners"
ref="innerSelect" ref="innerSelect"
> >
<template #prefix> <template #prefix>
@ -32,7 +31,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Select as ElSelect } from 'element-ui'; import { ElSelect } from 'element-plus';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
type InnerSelectRef = InstanceType<typeof ElSelect>; type InnerSelectRef = InstanceType<typeof ElSelect>;
@ -49,7 +48,8 @@ export default defineComponent({
ElSelect, ElSelect,
}, },
props: { props: {
value: {}, ...ElSelect.props,
modelValue: {},
size: { size: {
type: String, type: String,
default: 'large', 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'; import N8nSpinner from './Spinner.vue';
export default { export default {
@ -8,24 +8,25 @@ export default {
size: { size: {
control: { control: {
type: 'select', type: 'select',
options: ['small', 'medium', 'large'],
}, },
options: ['small', 'medium', 'large'],
}, },
type: { type: {
control: { control: {
type: 'select', type: 'select',
options: ['dots', 'ring'],
}, },
options: ['dots', 'ring'],
}, },
}, },
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nSpinner, N8nSpinner,
}, },
template: '<n8n-spinner v-bind="$props" />', template: '<n8n-spinner v-bind="args" />',
}); });
export const Spinner = Template.bind({}); export const Spinner = Template.bind({});

View file

@ -1,5 +1,5 @@
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import N8nSticky from './Sticky.vue'; import N8nSticky from './Sticky.vue';
export default { export default {
@ -47,12 +47,13 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nSticky, N8nSticky,
}, },
template: 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, methods,
}); });

View file

@ -1,7 +1,7 @@
import N8nTabs from './Tabs.vue'; import N8nTabs from './Tabs.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Atoms/Tabs', title: 'Atoms/Tabs',
@ -17,11 +17,12 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nTabs, 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>`, </n8n-tabs>`,
methods, methods,
data() { data() {

View file

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

View file

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

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import N8nTags from './Tags.vue'; import N8nTags from './Tags.vue';
export default { export default {
@ -8,11 +8,12 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nTags, N8nTags,
}, },
template: '<n8n-tags v-bind="$props"></n8n-tags>', template: '<n8n-tags v-bind="args"></n8n-tags>',
}); });
export const Tags = Template.bind({}); 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'; import N8nText from './Text.vue';
export default { export default {
@ -8,32 +8,33 @@ export default {
size: { size: {
control: { control: {
type: 'select', type: 'select',
options: ['xsmall', 'small', 'medium', 'large'],
}, },
options: ['xsmall', 'small', 'medium', 'large'],
}, },
color: { color: {
control: { control: {
type: 'select', 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 }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nText, 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({}); export const Text = Template.bind({});

View file

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

View file

@ -1,4 +1,4 @@
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import N8nTooltip from './Tooltip.vue'; import N8nTooltip from './Tooltip.vue';
export default { export default {
@ -36,12 +36,13 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nTooltip, N8nTooltip,
}, },
template: 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({}); export const Tooltip = Template.bind({});

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
import N8nUserSelect from './UserSelect.vue'; import N8nUserSelect from './UserSelect.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
export default { export default {
title: 'Modules/UserSelect', title: 'Modules/UserSelect',
@ -18,12 +18,13 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nUserSelect, N8nUserSelect,
}, },
template: 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, methods,
data() { data() {
return { return {

View file

@ -1,6 +1,6 @@
import N8nUsersList from './UsersList.vue'; import N8nUsersList from './UsersList.vue';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import type { StoryFn } from '@storybook/vue'; import type { StoryFn } from '@storybook/vue3';
import type { IUser } from '@/types'; import type { IUser } from '@/types';
export default { export default {
@ -18,12 +18,13 @@ const methods = {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
N8nUsersList, N8nUsersList,
}, },
template: 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, methods,
}); });

View file

@ -6,46 +6,46 @@ export { default as N8nAvatar } from './N8nAvatar';
export { default as N8nBadge } from './N8nBadge'; export { default as N8nBadge } from './N8nBadge';
export { default as N8nBlockUi } from './N8nBlockUi'; export { default as N8nBlockUi } from './N8nBlockUi';
export { default as N8nButton } from './N8nButton'; 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 N8nCallout } from './N8nCallout';
export { default as N8nCard } from './N8nCard'; export { default as N8nCard } from './N8nCard';
export { default as N8nDatatable } from './N8nDatatable'; export { default as N8nDatatable } from './N8nDatatable';
export { default as N8nFormBox } from './N8nFormBox'; // export { default as N8nFormBox } from './N8nFormBox';
export { default as N8nFormInputs } from './N8nFormInputs'; // export { default as N8nFormInputs } from './N8nFormInputs';
export { default as N8nFormInput } from './N8nFormInput'; // export { default as N8nFormInput } from './N8nFormInput';
export { default as N8nHeading } from './N8nHeading'; export { default as N8nHeading } from './N8nHeading';
export { default as N8nIcon } from './N8nIcon'; export { default as N8nIcon } from './N8nIcon';
export { default as N8nIconButton } from './N8nIconButton'; export { default as N8nIconButton } from './N8nIconButton';
export { default as N8nInfoAccordion } from './N8nInfoAccordion'; // export { default as N8nInfoAccordion } from './N8nInfoAccordion';
export { default as N8nInfoTip } from './N8nInfoTip'; // export { default as N8nInfoTip } from './N8nInfoTip';
export { default as N8nInput } from './N8nInput'; // export { default as N8nInput } from './N8nInput';
export { default as N8nInputLabel } from './N8nInputLabel'; // export { default as N8nInputLabel } from './N8nInputLabel';
export { default as N8nInputNumber } from './N8nInputNumber'; // export { default as N8nInputNumber } from './N8nInputNumber';
export { default as N8nLink } from './N8nLink'; // export { default as N8nLink } from './N8nLink';
export { default as N8nLoading } from './N8nLoading'; // export { default as N8nLoading } from './N8nLoading';
export { default as N8nMarkdown } from './N8nMarkdown'; // export { default as N8nMarkdown } from './N8nMarkdown';
export { default as N8nMenu } from './N8nMenu'; // export { default as N8nMenu } from './N8nMenu';
export { default as N8nMenuItem } from './N8nMenuItem'; // export { default as N8nMenuItem } from './N8nMenuItem';
export { default as N8nNodeCreatorNode } from './N8nNodeCreatorNode'; // export { default as N8nNodeCreatorNode } from './N8nNodeCreatorNode';
export { default as N8nNodeIcon } from './N8nNodeIcon'; // export { default as N8nNodeIcon } from './N8nNodeIcon';
export { default as N8nNotice } from './N8nNotice'; // export { default as N8nNotice } from './N8nNotice';
export { default as N8nOption } from './N8nOption'; // export { default as N8nOption } from './N8nOption';
export { default as N8nPopover } from './N8nPopover'; export { default as N8nPopover } from './N8nPopover';
export { default as N8nPulse } from './N8nPulse'; // export { default as N8nPulse } from './N8nPulse';
export { default as N8nRadioButtons } from './N8nRadioButtons'; // export { default as N8nRadioButtons } from './N8nRadioButtons';
export { default as N8nSelect } from './N8nSelect'; // export { default as N8nSelect } from './N8nSelect';
export { default as N8nSpinner } from './N8nSpinner'; // export { default as N8nSpinner } from './N8nSpinner';
export { default as N8nSticky } from './N8nSticky'; // export { default as N8nSticky } from './N8nSticky';
export { default as N8nTabs } from './N8nTabs'; // export { default as N8nTabs } from './N8nTabs';
export { default as N8nTag } from './N8nTag'; // export { default as N8nTag } from './N8nTag';
export { default as N8nTags } from './N8nTags'; // export { default as N8nTags } from './N8nTags';
export { default as N8nText } from './N8nText'; export { default as N8nText } from './N8nText';
export { default as N8nTooltip } from './N8nTooltip'; export { default as N8nTooltip } from './N8nTooltip';
export { default as N8nTree } from './N8nTree'; // export { default as N8nTree } from './N8nTree';
export { default as N8nUserInfo } from './N8nUserInfo'; // export { default as N8nUserInfo } from './N8nUserInfo';
export { default as N8nUserSelect } from './N8nUserSelect'; // export { default as N8nUserSelect } from './N8nUserSelect';
export { default as N8nUsersList } from './N8nUsersList'; // export { default as N8nUsersList } from './N8nUsersList';
export { default as N8nResizeWrapper } from './N8nResizeWrapper'; // export { default as N8nResizeWrapper } from './N8nResizeWrapper';
export { default as N8nRecycleScroller } from './N8nRecycleScroller'; // export { default as N8nRecycleScroller } from './N8nRecycleScroller';
export { default as N8nCheckbox } from './N8nCheckbox'; // export { default as N8nCheckbox } from './N8nCheckbox';
export { default as N8nColorPicker } from './N8nColorPicker'; // 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; const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
/** /**
* String format template * String format template
@ -12,34 +6,30 @@ const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
* https://github.com/Matt-Esch/string-template/index.js * https://github.com/Matt-Esch/string-template/index.js
*/ */
export default function () { export default function () {
/** function template(
* template value: string | ((...args: unknown[]) => string),
* ...args: Array<string | object>
* @param {String | Function} string ) {
* @param {Array} ...args
* @return {String}
*/
function template(value, ...args) {
if (typeof value === 'function') { if (typeof value === 'function') {
return value(args); return value(args);
} }
const string = value;
const str = value;
if (args.length === 1 && typeof args[0] === 'object') { if (args.length === 1 && typeof args[0] === 'object') {
args = args[0]; args = args[0] as unknown as Array<string | object>;
} }
if (!args || !args.hasOwnProperty) { 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; let result;
if (string[index - 1] === '{' && string[index + match.length] === '}') { if (str[index - 1] === '{' && str[index + match.length] === '}') {
return i; return i;
} else { } else {
result = hasOwn(args, i) ? args[i] : null; result = Object.hasOwn(args, i) ? args[i] : null;
if (result === null || result === undefined) { if (result === null || result === undefined) {
return ''; 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 { export default {
'nds.auth.roles.owner': 'Owner', 'nds.auth.roles.owner': 'Owner',
'nds.userInfo.you': '(you)', 'nds.userInfo.you': '(you)',
@ -8,15 +11,16 @@ export default {
'formInput.validator.fieldRequired': 'This field is required', 'formInput.validator.fieldRequired': 'This field is required',
'formInput.validator.minCharactersRequired': 'Must be at least {minimum} characters', 'formInput.validator.minCharactersRequired': 'Must be at least {minimum} characters',
'formInput.validator.maxCharactersRequired': 'Must be at most {maximum} 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' : ''}`; return `Must have at least ${config.minimum} number${config.minimum > 1 ? 's' : ''}`;
}, },
'formInput.validator.validEmailRequired': 'Must be a valid email', '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' : ''}`, `Must have at least ${config.minimum} uppercase character${config.minimum > 1 ? 's' : ''}`,
'formInput.validator.defaultPasswordRequirements': 'formInput.validator.defaultPasswordRequirements':
'8+ characters, at least 1 number and 1 capital letter', '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>`, 'sticky.markdownHint':
'tags.showMore': (count) => `+${count} more`, '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', 'datatable.pageSize': 'Page size',
}; } as N8nLocale;

View file

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import type { PluginObject } from 'vue'; import type { Plugin } from 'vue';
import { import {
N8nActionBox, N8nActionBox,
N8nActionDropdown, N8nActionDropdown,
@ -9,54 +9,54 @@ import {
N8nBadge, N8nBadge,
N8nBlockUi, N8nBlockUi,
N8nButton, N8nButton,
N8nElButton, // N8nElButton,
N8nCallout, N8nCallout,
N8nCard, N8nCard,
N8nDatatable, N8nDatatable,
N8nFormBox, // N8nFormBox,
N8nFormInputs, // N8nFormInputs,
N8nFormInput, // N8nFormInput,
N8nHeading, N8nHeading,
N8nIcon, N8nIcon,
N8nIconButton, N8nIconButton,
N8nInfoAccordion, // N8nInfoAccordion,
N8nInfoTip, // N8nInfoTip,
N8nInput, // N8nInput,
N8nInputLabel, // N8nInputLabel,
N8nInputNumber, // N8nInputNumber,
N8nLink, // N8nLink,
N8nLoading, // N8nLoading,
N8nMarkdown, // N8nMarkdown,
N8nMenu, // N8nMenu,
N8nMenuItem, // N8nMenuItem,
N8nNodeCreatorNode, // N8nNodeCreatorNode,
N8nNodeIcon, // N8nNodeIcon,
N8nNotice, // N8nNotice,
N8nOption, // N8nOption,
N8nPopover, N8nPopover,
N8nPulse, // N8nPulse,
N8nRadioButtons, // N8nRadioButtons,
N8nSelect, // N8nSelect,
N8nSpinner, // N8nSpinner,
N8nSticky, // N8nSticky,
N8nTabs, // N8nTabs,
N8nTag, // N8nTag,
N8nTags, // N8nTags,
N8nText, N8nText,
N8nTooltip, N8nTooltip,
N8nTree, // N8nTree,
N8nUserInfo, // N8nUserInfo,
N8nUserSelect, // N8nUserSelect,
N8nUsersList, // N8nUsersList,
N8nResizeWrapper, // N8nResizeWrapper,
N8nRecycleScroller, // N8nRecycleScroller,
N8nCheckbox, // N8nCheckbox,
N8nColorPicker, // N8nColorPicker,
} from './components'; } from './components';
export const N8nPlugin: PluginObject<{}> = { export const N8nPlugin: Plugin<{}> = {
install: (app) => { install: (app) => {
app.component('n8n-info-accordion', N8nInfoAccordion); // app.component('n8n-info-accordion', N8nInfoAccordion);
app.component('n8n-action-box', N8nActionBox); app.component('n8n-action-box', N8nActionBox);
app.component('n8n-action-dropdown', N8nActionDropdown); app.component('n8n-action-dropdown', N8nActionDropdown);
app.component('n8n-action-toggle', N8nActionToggle); app.component('n8n-action-toggle', N8nActionToggle);
@ -65,47 +65,47 @@ export const N8nPlugin: PluginObject<{}> = {
app.component('n8n-badge', N8nBadge); app.component('n8n-badge', N8nBadge);
app.component('n8n-block-ui', N8nBlockUi); app.component('n8n-block-ui', N8nBlockUi);
app.component('n8n-button', N8nButton); app.component('n8n-button', N8nButton);
app.component('el-button', N8nElButton); // app.component('el-button', N8nElButton);
app.component('n8n-callout', N8nCallout); app.component('n8n-callout', N8nCallout);
app.component('n8n-card', N8nCard); app.component('n8n-card', N8nCard);
app.component('n8n-datatable', N8nDatatable); app.component('n8n-datatable', N8nDatatable);
app.component('n8n-form-box', N8nFormBox); // app.component('n8n-form-box', N8nFormBox);
app.component('n8n-form-inputs', N8nFormInputs); // app.component('n8n-form-inputs', N8nFormInputs);
app.component('n8n-form-input', N8nFormInput); // app.component('n8n-form-input', N8nFormInput);
app.component('n8n-heading', N8nHeading);
app.component('n8n-icon', N8nIcon); app.component('n8n-icon', N8nIcon);
app.component('n8n-icon-button', N8nIconButton); app.component('n8n-icon-button', N8nIconButton);
app.component('n8n-info-tip', N8nInfoTip); // app.component('n8n-info-tip', N8nInfoTip);
app.component('n8n-input', N8nInput); // app.component('n8n-input', N8nInput);
app.component('n8n-input-label', N8nInputLabel); // app.component('n8n-input-label', N8nInputLabel);
app.component('n8n-input-number', N8nInputNumber); // app.component('n8n-input-number', N8nInputNumber);
app.component('n8n-loading', N8nLoading); // app.component('n8n-loading', N8nLoading);
app.component('n8n-heading', N8nHeading); // app.component('n8n-link', N8nLink);
app.component('n8n-link', N8nLink); // app.component('n8n-markdown', N8nMarkdown);
app.component('n8n-markdown', N8nMarkdown); // app.component('n8n-menu', N8nMenu);
app.component('n8n-menu', N8nMenu); // app.component('n8n-menu-item', N8nMenuItem);
app.component('n8n-menu-item', N8nMenuItem); // app.component('n8n-node-creator-node', N8nNodeCreatorNode);
app.component('n8n-node-creator-node', N8nNodeCreatorNode); // app.component('n8n-node-icon', N8nNodeIcon);
app.component('n8n-node-icon', N8nNodeIcon); // app.component('n8n-notice', N8nNotice);
app.component('n8n-notice', N8nNotice); // app.component('n8n-option', N8nOption);
app.component('n8n-option', N8nOption);
app.component('n8n-popover', N8nPopover); app.component('n8n-popover', N8nPopover);
app.component('n8n-pulse', N8nPulse); // app.component('n8n-pulse', N8nPulse);
app.component('n8n-select', N8nSelect); // app.component('n8n-select', N8nSelect);
app.component('n8n-spinner', N8nSpinner); // app.component('n8n-spinner', N8nSpinner);
app.component('n8n-sticky', N8nSticky); // app.component('n8n-sticky', N8nSticky);
app.component('n8n-radio-buttons', N8nRadioButtons); // app.component('n8n-radio-buttons', N8nRadioButtons);
app.component('n8n-tags', N8nTags); // app.component('n8n-tags', N8nTags);
app.component('n8n-tabs', N8nTabs); // app.component('n8n-tabs', N8nTabs);
app.component('n8n-tag', N8nTag); // app.component('n8n-tag', N8nTag);
app.component('n8n-text', N8nText); app.component('n8n-text', N8nText);
app.component('n8n-tooltip', N8nTooltip); app.component('n8n-tooltip', N8nTooltip);
app.component('n8n-user-info', N8nUserInfo); // app.component('n8n-user-info', N8nUserInfo);
app.component('n8n-tree', N8nTree); // app.component('n8n-tree', N8nTree);
app.component('n8n-users-list', N8nUsersList); // app.component('n8n-users-list', N8nUsersList);
app.component('n8n-user-select', N8nUserSelect); // app.component('n8n-user-select', N8nUserSelect);
app.component('n8n-resize-wrapper', N8nResizeWrapper); // app.component('n8n-resize-wrapper', N8nResizeWrapper);
app.component('n8n-recycle-scroller', N8nRecycleScroller); // app.component('n8n-recycle-scroller', N8nRecycleScroller);
app.component('n8n-checkbox', N8nCheckbox); // app.component('n8n-checkbox', N8nCheckbox);
app.component('n8n-color-picker', N8nColorPicker); // 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 { export default {
title: 'Utilities/Lists', 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'; import SpacingPreview from '../components/SpacingPreview.vue';
export default { export default {
@ -6,11 +6,12 @@ export default {
}; };
const Template: StoryFn = (args, { argTypes }) => ({ const Template: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes), props: Object.keys(argTypes),
components: { components: {
SpacingPreview, SpacingPreview,
}, },
template: '<spacing-preview v-bind="$props" />', template: '<spacing-preview v-bind="args" />',
}); });
export const Padding = Template.bind({}); 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 './button';
export * from './datatable'; export * from './datatable';
export * from './form'; export * from './form';
export * from './i18n';
export * from './menu'; export * from './menu';
export * from './router'; export * from './router';
export * from './user'; 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 { resolve } from 'path';
import { defineConfig, mergeConfig } from 'vite'; import { defineConfig, mergeConfig } from 'vite';
import { defineConfig as defineVitestConfig } from 'vitest/config'; import { defineConfig as defineVitestConfig } from 'vitest/config';
@ -11,7 +11,6 @@ export default mergeConfig(
resolve: { resolve: {
alias: { alias: {
'@': resolve(__dirname, 'src'), '@': resolve(__dirname, 'src'),
'vue2-boring-avatars': require.resolve('vue2-boring-avatars'),
}, },
}, },
build: { build: {

View file

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

View file

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

View file

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