├── components ├── theme-chalk │ ├── x6-sub-menu.scss │ ├── variables.scss │ ├── x6-tooltip.js │ ├── x6-menu-item.scss │ ├── x6-scrollbox.scss │ ├── x6-item.scss │ ├── x6-context-menu.scss │ ├── x6-menubar-item.scss │ ├── x6-tooltip.scss │ ├── x6-divider.scss │ ├── x6-group.scss │ ├── x6-dropdown.scss │ ├── x6-split-box.scss │ ├── index.scss │ ├── x6-menubar.scss │ ├── x6-color-picker.scss │ └── x6-menu.scss ├── x6-item │ └── index.js ├── x6-group │ └── index.js ├── x6-divider │ └── index.js ├── x6-dropdown │ ├── index.js │ └── Dropdown.vue ├── x6-sub-menu │ └── index.js ├── x6-menu-item │ └── index.js ├── x6-tooltip │ ├── index.js │ └── Tooltip.vue ├── x6-split-box │ ├── index.js │ ├── Box.vue │ └── Resizer.vue ├── x6-color-picker │ └── index.js ├── x6-context-menu │ ├── index.js │ └── ContextMenu.vue ├── x6-scrollbox │ └── index.js ├── x6-menubar-item │ └── index.js ├── x6-menubar │ ├── index.js │ └── Menubar.vue ├── x6-toolbar │ ├── index.js │ ├── Group.vue │ ├── Toolbar.vue │ └── ItemJsx.vue ├── overlayscrollbars-vue3 │ ├── OverlayScrollbarsPlugin.js │ └── OverlayScrollbarsComponent.vue ├── x6-menu │ ├── index.js │ ├── Divider.vue │ ├── Menu.vue │ ├── SubMenu.vue │ └── MenuItem.vue ├── util │ ├── install.js │ └── dom │ │ ├── animationFrame.js │ │ └── MouseMoveTracker.js └── index.js ├── lib ├── x6-menu-item.css ├── x6-divider.css ├── x6-menubar-item.css ├── x6-group.css ├── x6-split-box.css ├── x6-divider.js ├── x6-group.js └── x6-color-picker.css ├── docs ├── .prettierrc ├── public │ ├── logo.png │ └── favicon.png ├── .vitepress │ ├── dist │ │ ├── logo.png │ │ ├── favicon.png │ │ ├── assets │ │ │ ├── source-code-icon.7846e45d.svg │ │ │ ├── copy-icon.7c70d689.svg │ │ │ ├── components_introduction.md.31828ee2.lean.js │ │ │ ├── components_guide.md.c2aa522e.lean.js │ │ │ ├── chicken.ff0991b0.svg │ │ │ ├── index.md.55a8372d.js │ │ │ ├── index.md.55a8372d.lean.js │ │ │ ├── Home.29e71739.js │ │ │ └── components_introduction.md.31828ee2.js │ │ └── hashmap.json │ ├── utils │ │ ├── paths.js │ │ ├── toggle.js │ │ ├── useToc.js │ │ ├── highlight.js │ │ └── activeBar.js │ ├── components │ │ ├── icons │ │ │ ├── source-code-icon.svg │ │ │ └── copy-icon.svg │ │ ├── SourceCode.vue │ │ ├── Example.vue │ │ ├── TocContentNav.vue │ │ └── Demo.vue │ ├── theme │ │ ├── styles │ │ │ └── index.css │ │ ├── register-components.js │ │ └── index.js │ ├── config │ │ ├── nav.js │ │ ├── sidebar.js │ │ └── plugins.js │ └── config.js ├── components │ ├── tooltip │ │ ├── hover.vue │ │ ├── click.vue │ │ ├── location.vue │ │ ├── theme.vue │ │ ├── placement.vue │ │ └── index.md │ ├── menu │ │ ├── basic.vue │ │ ├── icon.vue │ │ ├── chicken.svg │ │ ├── event.vue │ │ ├── submenu.vue │ │ ├── disabled.vue │ │ ├── hotKey.vue │ │ └── index.md │ ├── dropdown │ │ ├── contextMenu.vue │ │ ├── hover.vue │ │ ├── placement.vue │ │ ├── location.vue │ │ ├── theme.vue │ │ └── index.md │ ├── colorPicker │ │ ├── disabled.vue │ │ ├── init.vue │ │ ├── hideAlpha.vue │ │ ├── predefineColors.vue │ │ └── index.md │ ├── button │ │ ├── index.md │ │ └── demo.vue │ ├── splitbox │ │ ├── noDivider.vue │ │ ├── basic.vue │ │ ├── index.md │ │ └── complex.vue │ ├── contextmenu │ │ ├── basic.vue │ │ └── index.md │ ├── toolbar │ │ ├── basic.vue │ │ ├── tooltip.vue │ │ ├── dropdownArrow.vue │ │ ├── event.vue │ │ ├── icon.vue │ │ └── index.md │ ├── menubar │ │ ├── index.md │ │ └── basic.vue │ ├── introduction.md │ ├── scrollbox │ │ ├── index.md │ │ └── xy.vue │ └── guide.md ├── index.md ├── vite.config.js └── package.json ├── .gitignore ├── README.md └── package.json /components/theme-chalk/x6-sub-menu.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/theme-chalk/variables.scss: -------------------------------------------------------------------------------- 1 | $x6-prefix: x6; -------------------------------------------------------------------------------- /components/theme-chalk/x6-tooltip.js: -------------------------------------------------------------------------------- 1 | import './x6-tooltip.scss' -------------------------------------------------------------------------------- /lib/x6-menu-item.css: -------------------------------------------------------------------------------- 1 | .x6-menu-item { 2 | position: inherit; 3 | } -------------------------------------------------------------------------------- /docs/.prettierrc: -------------------------------------------------------------------------------- 1 | semi: false 2 | singleQuote: true 3 | printWidth: 80 4 | -------------------------------------------------------------------------------- /lib/x6-divider.css: -------------------------------------------------------------------------------- 1 | .x6-menu-item-divider { 2 | position: inherit; 3 | } -------------------------------------------------------------------------------- /lib/x6-menubar-item.css: -------------------------------------------------------------------------------- 1 | .x6-menubar-item { 2 | position: inherit; 3 | } -------------------------------------------------------------------------------- /lib/x6-group.css: -------------------------------------------------------------------------------- 1 | .x6-toolbar-group { 2 | position: inherit; 3 | height: 100%; 4 | } -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaodai123/x6-vue3-components/HEAD/docs/public/logo.png -------------------------------------------------------------------------------- /docs/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaodai123/x6-vue3-components/HEAD/docs/public/favicon.png -------------------------------------------------------------------------------- /docs/.vitepress/dist/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaodai123/x6-vue3-components/HEAD/docs/.vitepress/dist/logo.png -------------------------------------------------------------------------------- /docs/.vitepress/dist/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaodai123/x6-vue3-components/HEAD/docs/.vitepress/dist/favicon.png -------------------------------------------------------------------------------- /components/theme-chalk/x6-menu-item.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $menu-item-prefix-cls: '#{$x6-prefix}-menu-item'; 4 | .#{$menu-item-prefix-cls} { 5 | position: inherit; 6 | } -------------------------------------------------------------------------------- /components/theme-chalk/x6-scrollbox.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $scrollbox-prefix-cls: '#{$x6-prefix}-scrollbox'; 4 | .#{$scrollbox-prefix-cls} { 5 | position: inherit; 6 | } -------------------------------------------------------------------------------- /components/theme-chalk/x6-item.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $toolbar-item-prefix-cls: '#{$x6-prefix}-toolbar-item'; 4 | .#{$toolbar-item-prefix-cls} { 5 | position: inherit; 6 | } -------------------------------------------------------------------------------- /components/x6-item/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | import Item from '../x6-toolbar/Item.vue' 3 | 4 | export const X6Item = withInstall(Item) 5 | 6 | export default X6Item -------------------------------------------------------------------------------- /components/theme-chalk/x6-context-menu.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $context-menu-prefix-cls: '#{$x6-prefix}-context-menu'; 4 | .#{$context-menu-prefix-cls} { 5 | position: inherit; 6 | } -------------------------------------------------------------------------------- /components/theme-chalk/x6-menubar-item.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $menubar-item-prefix-cls: '#{$x6-prefix}-menubar-item'; 4 | .#{$menubar-item-prefix-cls} { 5 | position: inherit; 6 | } -------------------------------------------------------------------------------- /components/theme-chalk/x6-tooltip.scss: -------------------------------------------------------------------------------- 1 | div[data-tippy-root] { 2 | pointer-events: unset!important; 3 | } 4 | .tippy-box[data-theme~=light] { 5 | box-shadow: 0 2px 10px rgb(0 0 0 / 12%)!important; 6 | } -------------------------------------------------------------------------------- /components/x6-group/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | import Group from '../x6-toolbar/Group.vue' 3 | 4 | export const X6Group = withInstall(Group) 5 | 6 | export default X6Group -------------------------------------------------------------------------------- /components/theme-chalk/x6-divider.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $menu-item-divider-prefix-cls: '#{$x6-prefix}-menu-item-divider'; 4 | .#{$menu-item-divider-prefix-cls} { 5 | position: inherit; 6 | } -------------------------------------------------------------------------------- /components/x6-divider/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | import Divider from '../x6-menu/Divider.vue' 3 | 4 | export const X6Divider = withInstall(Divider) 5 | 6 | export default X6Divider -------------------------------------------------------------------------------- /components/x6-dropdown/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | 3 | import Dropdown from './Dropdown.vue' 4 | 5 | export const X6Dropdown = withInstall(Dropdown) 6 | export default X6Dropdown 7 | -------------------------------------------------------------------------------- /components/x6-sub-menu/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | import SubMenu from '../x6-menu/SubMenu.vue' 3 | 4 | export const X6SubMenu = withInstall(SubMenu) 5 | 6 | export default X6SubMenu -------------------------------------------------------------------------------- /components/theme-chalk/x6-group.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $toolbar-group-prefix-cls: '#{$x6-prefix}-toolbar-group'; 4 | .#{$toolbar-group-prefix-cls} { 5 | position: inherit; 6 | height: 100%; 7 | } -------------------------------------------------------------------------------- /components/x6-menu-item/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | import MenuItem from '../x6-menu/MenuItem.vue' 3 | 4 | export const X6MenuItem = withInstall(MenuItem) 5 | 6 | export default X6MenuItem -------------------------------------------------------------------------------- /components/x6-tooltip/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall, withNoopInstall } from '../util/install' 2 | import Tooltip from './Tooltip.vue' 3 | 4 | export const X6Tooltip = withInstall(Tooltip) 5 | 6 | export default X6Tooltip 7 | -------------------------------------------------------------------------------- /docs/.vitepress/utils/paths.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | 3 | export const vpRoot = path.resolve(__dirname, '..') 4 | export const docRoot = path.resolve(vpRoot, '..') 5 | export const projRoot = path.resolve(docRoot, '..') -------------------------------------------------------------------------------- /components/x6-split-box/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall, withNoopInstall } from '../util/install' 2 | import SplitBox from './SplitBox.vue' 3 | 4 | export const X6SplitBox = withInstall(SplitBox) 5 | 6 | export default X6SplitBox 7 | -------------------------------------------------------------------------------- /components/x6-color-picker/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | 3 | import ColorPicker from './ColorPicker.vue' 4 | 5 | export const X6ColorPicker = withInstall(ColorPicker) 6 | export default X6ColorPicker 7 | -------------------------------------------------------------------------------- /components/x6-context-menu/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | 3 | import ContextMenu from './ContextMenu.vue' 4 | 5 | export const X6ContextMenu = withInstall(ContextMenu) 6 | export default X6ContextMenu 7 | -------------------------------------------------------------------------------- /components/x6-scrollbox/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall, withNoopInstall } from '../util/install' 2 | import Scrollbox from './Scrollbox.vue' 3 | 4 | export const X6Scrollbox = withInstall(Scrollbox) 5 | 6 | export default X6Scrollbox 7 | -------------------------------------------------------------------------------- /components/theme-chalk/x6-dropdown.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $dropdown-prefix-cls: '#{$x6-prefix}-dropdown'; 4 | .#{$dropdown-prefix-cls} { 5 | position: inherit; 6 | max-height: 450px; 7 | overflow-y: auto; 8 | } -------------------------------------------------------------------------------- /components/x6-menubar-item/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall } from '../util/install' 2 | import MenubarItem from '../x6-menubar/MenubarItem.vue' 3 | 4 | export const X6MenubarItem = withInstall(MenubarItem) 5 | 6 | export default X6MenubarItem -------------------------------------------------------------------------------- /docs/components/tooltip/hover.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/tooltip/click.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /lib/x6-split-box.css: -------------------------------------------------------------------------------- 1 | .x6-split-box-vertical > .x6-split-box-resizer { 2 | width: 4px; 3 | margin: 0 -2px; 4 | background: transparent; 5 | } 6 | .x6-split-box-horizontal > .x6-split-box-resizer { 7 | height: 4px; 8 | margin: -2px; 9 | background: transparent; 10 | } 11 | .x6-split-box-disabled > .x6-split-box-resizer { 12 | cursor: default; 13 | } -------------------------------------------------------------------------------- /components/x6-menubar/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall, withNoopInstall } from '../util/install' 2 | import Menubar from './Menubar.vue' 3 | import MenubarItem from './MenubarItem.vue' 4 | 5 | export const X6Menubar = withInstall(Menubar, { 6 | MenubarItem 7 | }) 8 | 9 | export default X6Menubar 10 | 11 | export const X6MenubarItem = withNoopInstall(MenubarItem) -------------------------------------------------------------------------------- /docs/.vitepress/components/icons/source-code-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/source-code-icon.7846e45d.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/x6-toolbar/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall, withNoopInstall } from '../util/install' 2 | import Toolbar from './Toolbar.vue' 3 | import Group from './Group.vue' 4 | import Item from './Item.vue' 5 | 6 | export const X6Toolbar = withInstall(Toolbar, { 7 | Group, 8 | Item 9 | }) 10 | 11 | export default X6Toolbar 12 | 13 | export const X6Group = withNoopInstall(Group) 14 | export const X6Item = withNoopInstall(Item) -------------------------------------------------------------------------------- /docs/.vitepress/components/icons/copy-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/copy-icon.7c70d689.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --c-brand: #873bf4; 3 | --c-brand-light: #873bf4; 4 | } 5 | .m-0 { 6 | margin: 0; 7 | } 8 | .container { 9 | padding: unset!important; 10 | margin-left: 5rem!important; 11 | } 12 | .next-and-prev-link { 13 | padding-bottom: 5rem!important; 14 | } 15 | table tr td:nth-child(2) { 16 | max-width: 350px; 17 | } 18 | table tr td:nth-child(4) { 19 | max-width: 200px; 20 | } 21 | -------------------------------------------------------------------------------- /docs/components/menu/basic.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/config/nav.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | text: '首页', 4 | link: '/', 5 | }, 6 | { 7 | text: '组件', 8 | link: '/components/introduction', 9 | }, 10 | { 11 | text: '案例', 12 | link: 'https://daizhigitee.gitee.io/x6-vue3-components-examples/', 13 | }, 14 | { 15 | text: 'GitHub', 16 | link: 'https://github.com/xiaodai123/x6-vue3-components', 17 | } 18 | ] -------------------------------------------------------------------------------- /docs/.vitepress/utils/toggle.js: -------------------------------------------------------------------------------- 1 | import { isRef, ref } from 'vue' 2 | import { isBoolean } from '@vueuse/core' 3 | 4 | export const useToggle = (getToggled) => { 5 | const val = isRef(getToggled) 6 | ? getToggled 7 | : ref(isBoolean(getToggled) ? getToggled : false) 8 | 9 | return [ 10 | val, 11 | (toggle) => { 12 | val.value = isBoolean(toggle) ? toggle : !val.value 13 | }, 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /components/overlayscrollbars-vue3/OverlayScrollbarsPlugin.js: -------------------------------------------------------------------------------- 1 | import OverlayScrollbars from 'overlayscrollbars'; 2 | import OverlayScrollbarsComponent from './OverlayScrollbarsComponent.vue'; 3 | 4 | export const OverlayScrollbarsPlugin = { 5 | install(app, options) { 6 | if (options) { 7 | OverlayScrollbars.defaultOptions(options); 8 | } 9 | 10 | app.component('overlay-scrollbars', OverlayScrollbarsComponent); 11 | } 12 | } -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /logo.png 4 | heroAlt: Logo image 5 | heroText: X6 图编辑引擎 6 | tagline: X6 Vue3 Components 7 | actionText: Get Started 8 | actionLink: /components/guide 9 | features: 10 | - title: 快速上手,极易定制 11 | details: 提供基于低学习成本的 SVG/HTML/CSS 的节点定制能力. 12 | - title: 组件完备,开箱即用 13 | details: 内置 10+ 图编辑场景的配套扩展,如框选、对齐线、小地图等. 14 | - title: 灵活,可扩展 15 | details: 画布、节点、边、属性、工具等均可以通过注册机制自由、灵活扩展. 16 | footer: MIT Licensed | Copyright © 2021-present 17 | --- -------------------------------------------------------------------------------- /docs/components/dropdown/contextMenu.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/hashmap.json: -------------------------------------------------------------------------------- 1 | {"components_button_index.md":"495030c0","components_colorpicker_index.md":"6ee199dc","components_contextmenu_index.md":"fc9327c4","components_dropdown_index.md":"be72cc1a","components_guide.md":"c2aa522e","components_introduction.md":"31828ee2","components_menu_index.md":"ea250e27","components_menubar_index.md":"4057061a","components_scrollbox_index.md":"7ab67c5a","components_splitbox_index.md":"e1a91b5f","components_toolbar_index.md":"b753f2ac","components_tooltip_index.md":"edfd4750","index.md":"55a8372d"} 2 | -------------------------------------------------------------------------------- /components/x6-menu/index.js: -------------------------------------------------------------------------------- 1 | import { withInstall, withNoopInstall } from '../util/install' 2 | import Menu from './Menu.vue' 3 | import SubMenu from './SubMenu.vue' 4 | import MenuItem from './MenuItem.vue' 5 | import Divider from './Divider.vue' 6 | 7 | export const X6Menu = withInstall(Menu, { 8 | SubMenu, 9 | MenuItem, 10 | Divider 11 | }) 12 | 13 | export default X6Menu 14 | 15 | export const X6SubMenu = withNoopInstall(SubMenu) 16 | export const X6MenuItem = withNoopInstall(MenuItem) 17 | export const X6Divider = withNoopInstall(Divider) -------------------------------------------------------------------------------- /docs/components/dropdown/hover.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/colorPicker/disabled.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /docs/components/colorPicker/init.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /components/util/install.js: -------------------------------------------------------------------------------- 1 | import { NOOP } from '@vue/shared' 2 | export const withInstall = (main, extra = {}) => { 3 | main.install = (app) => { 4 | for (const comp of [main, ...Object.values(extra)]) { 5 | app.component(comp.name, comp) 6 | } 7 | } 8 | 9 | if (extra) { 10 | for (const [key, comp] of Object.entries(extra)) { 11 | main[key] = comp 12 | } 13 | } 14 | return main 15 | } 16 | 17 | export const withNoopInstall = (component) => { 18 | component.install = NOOP 19 | 20 | return component 21 | } -------------------------------------------------------------------------------- /components/theme-chalk/x6-split-box.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $splitBox-prefix-cls: '#{$x6-prefix}-split-box'; 4 | 5 | .#{$splitBox-prefix-cls} { 6 | &-vertical > &-resizer { 7 | width: 4px; 8 | margin: 0 -2px; 9 | background: transparent; 10 | // background: #e9e9e9; 11 | } 12 | 13 | &-horizontal > &-resizer { 14 | height: 4px; 15 | margin: -2px; 16 | background: transparent; 17 | // background: #e9e9e9; 18 | } 19 | 20 | &-disabled > &-resizer { 21 | cursor: default; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/components/colorPicker/hideAlpha.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /docs/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | export default defineConfig({ 3 | css: { 4 | postcss: { 5 | plugins: [ 6 | { 7 | postcssPlugin: 'internal:charset-removal', 8 | AtRule: { 9 | charset: (atRule) => { 10 | if (atRule.name === 'charset') { 11 | atRule.remove(); 12 | } 13 | } 14 | } 15 | } 16 | ] 17 | } 18 | } 19 | }) -------------------------------------------------------------------------------- /components/theme-chalk/index.scss: -------------------------------------------------------------------------------- 1 | @use './variables.scss.scss'; 2 | // component styles 3 | @use './x6-color-picker.scss'; 4 | @use './x6-context-menu.scss'; 5 | @use './x6-divider.scss'; 6 | @use './x6-dropdown.scss'; 7 | @use './x6-group.scss'; 8 | @use './x6-item.scss'; 9 | @use './x6-menu.scss'; 10 | @use './x6-menubar.scss'; 11 | @use './x6-menubar-item.scss'; 12 | @use './x6-menu-item.scss'; 13 | @use './x6-scrollbox.scss'; 14 | @use './x6-split-box.scss'; 15 | @use './x6-sub-menu.scss'; 16 | @use './x6-toolbar.scss'; 17 | @use './x6-tooltip.scss'; 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/register-components.js: -------------------------------------------------------------------------------- 1 | import Demo from '../components/Demo.vue' 2 | import Example from '../components/Example.vue' 3 | import SourceCode from '../components/SourceCode.vue' 4 | import TocContentNav from '../components/TocContentNav.vue' 5 | import 'x6-vue3-components/lib/x6-vue3-components.min.css' 6 | import x6Vue3Components from 'x6-vue3-components' 7 | export function registerComponents(app) { 8 | app.component('Demo', Demo) 9 | app.component('Example', Example) 10 | app.component('SourceCode', SourceCode) 11 | app.component('TocContentNav', TocContentNav) 12 | app.use(x6Vue3Components) 13 | } 14 | -------------------------------------------------------------------------------- /components/x6-menu/Divider.vue: -------------------------------------------------------------------------------- 1 | 4 | 22 | -------------------------------------------------------------------------------- /docs/components/button/index.md: -------------------------------------------------------------------------------- 1 | # Button 按钮 2 | 3 | 常用的操作按钮。 4 | 5 | ## 基础用法 6 | 7 | 基础的按钮用法。 8 | 9 | :::demo The amount is defined with `value` which accepts `Number` or `String`. 10 | 11 | button/demo 12 | 13 | ::: 14 | 15 | ## Attributes 16 | 17 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 18 | | ------- | ------ | ------- | -------------------------------------------------- | ------- | 19 | | size | 尺寸 | string | large / small / mini | default | 20 | | type | 类型 | string | primary / success / warning / info / danger / text | primary | 21 | | loading | 加载中 | boolean | — | false | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/components_introduction.md.31828ee2.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as a,o as r,c as l,d as e,b as s,t as i,e as o}from"./app.7f45bc5d.js";const b='{"title":"\u7B80\u4ECB","description":"","frontmatter":{"title":"\u7B80\u4ECB"},"headers":[{"level":2,"title":"\u2728 \u7279\u6027","slug":"\u2728-\u7279\u6027"},{"level":2,"title":"\u{1F349} \u4F7F\u7528\u6587\u6863","slug":"\u{1F349}-\u4F7F\u7528\u6587\u6863"}],"relativePath":"components/introduction.md"}',n={},p={id:"frontmatter-title",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#frontmatter-title"},"#",-1),h=o("",10);function c(t,m,d,f,u,v){return r(),l("div",null,[e("h1",p,[g,s(" "+i(t.$frontmatter.title),1)]),h])}var x=a(n,[["render",c]]);export{b as __pageData,x as default}; 2 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/components_guide.md.c2aa522e.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as a,o as t,c as p,d as n,b as e,t as o,e as c}from"./app.7f45bc5d.js";const y='{"title":"\u5F00\u53D1\u6307\u5357","description":"","frontmatter":{"title":"\u5F00\u53D1\u6307\u5357"},"headers":[{"level":2,"title":"\u5B89\u88C5","slug":"\u5B89\u88C5"},{"level":2,"title":"\u4F7F\u7528","slug":"\u4F7F\u7528"},{"level":2,"title":"\u7EC4\u4EF6","slug":"\u7EC4\u4EF6"}],"relativePath":"components/guide.md"}',l={},r={id:"frontmatter-title",tabindex:"-1"},i=n("a",{class:"header-anchor",href:"#frontmatter-title"},"#",-1),u=c("",18);function k(s,d,m,f,g,h){return t(),p("div",null,[n("h1",r,[i,e(" "+o(s.$frontmatter.title),1)]),u])}var v=a(l,[["render",k]]);export{y as __pageData,v as default}; 2 | -------------------------------------------------------------------------------- /docs/.vitepress/components/SourceCode.vue: -------------------------------------------------------------------------------- 1 | 4 | 25 | 31 | -------------------------------------------------------------------------------- /components/util/dom/animationFrame.js: -------------------------------------------------------------------------------- 1 | let animationFrameTime = 0 2 | 3 | const nativeRequestAnimationFrame = 4 | window.requestAnimationFrame || window.webkitRequestAnimationFrame 5 | 6 | export const cancelAnimationFrame = ( 7 | window.cancelAnimationFrame || 8 | window.webkitCancelAnimationFrame || 9 | window.clearTimeout 10 | ).bind(window) 11 | 12 | export const requestAnimationFrame = nativeRequestAnimationFrame 13 | ? nativeRequestAnimationFrame.bind(window) 14 | : (callback) => { 15 | const currTime = Date.now() 16 | const timeDelay = Math.max(0, 16 - (currTime - animationFrameTime)) 17 | animationFrameTime = currTime + timeDelay 18 | return window.setTimeout(() => { 19 | callback(Date.now()) 20 | }, timeDelay) 21 | } 22 | -------------------------------------------------------------------------------- /docs/components/tooltip/location.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | import theme from 'vitepress/dist/client/theme-default' 2 | import { registerComponents } from './register-components' 3 | import 'normalize.css' 4 | import ElementPlus from 'element-plus' 5 | import 'element-plus/dist/index.css' 6 | import * as ElIcons from "@element-plus/icons" 7 | import './styles/index.css' 8 | import './styles/code.scss' 9 | 10 | 11 | export default { 12 | ...theme, 13 | enhanceApp({ app, router, siteData }) { 14 | // app is the Vue 3 app instance from createApp() 15 | // router is VitePress' custom router (see `lib/app/router.js`) 16 | // siteData is a ref of current site-level metadata. 17 | app.use(ElementPlus) 18 | 19 | for (const name in ElIcons){ 20 | app.component(name, ElIcons[name]) 21 | } 22 | 23 | registerComponents(app) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /components/x6-toolbar/Group.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | -------------------------------------------------------------------------------- /docs/components/menu/icon.vue: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /docs/components/splitbox/noDivider.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/splitbox/basic.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/menu/chicken.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/chicken.ff0991b0.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/utils/useToc.js: -------------------------------------------------------------------------------- 1 | import { computed } from 'vue' 2 | import { useData } from 'vitepress' 3 | 4 | export const useToc = () => { 5 | const { page } = useData() 6 | 7 | return computed(() => resolveHeaders(page.value.headers)) 8 | } 9 | 10 | export const resolveHeaders = (headers) => { 11 | return mapHeaders(groupHeaders(headers)) 12 | } 13 | 14 | export function groupHeaders(headers) { 15 | headers = headers.map((h) => Object.assign({}, h)) 16 | let lastH2 17 | 18 | headers.forEach((h) => { 19 | if (h.level === 2) { 20 | lastH2 = h 21 | } else if (lastH2) { 22 | (lastH2.children || (lastH2.children = [])).push(h) 23 | } 24 | }) 25 | return headers.filter((h) => h.level === 2) 26 | } 27 | 28 | export function mapHeaders(headers) { 29 | return headers.map((header) => ({ 30 | text: header.title, 31 | link: `#${header.slug}`, 32 | children: header.children ? mapHeaders(header.children) : undefined, 33 | })) 34 | } 35 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@x6-vue3-components/docs", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "@x6-vue3-components/docs", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "docs:dev": "vitepress dev .", 9 | "docs:build": "vitepress build .", 10 | "docs:serve": "vitepress serve ." 11 | }, 12 | "author": "daizhi", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@docsearch/js": "^3.0.0-alpha.50", 16 | "@element-plus/icons": "0.0.11", 17 | "@vueuse/core": "^7.6.1", 18 | "element-plus": "^2.0.2", 19 | "normalize.css": "^8.0.1", 20 | "prettier": "^2.5.1", 21 | "vite": "^2.8.2", 22 | "vitepress": "^0.22.1", 23 | "x6-vue3-components": "^1.1.3" 24 | }, 25 | "devDependencies": { 26 | "cross-env": "^7.0.3", 27 | "escape-html": "^1.0.3", 28 | "markdown-it": "^12.3.2", 29 | "markdown-it-anchor": "^8.4.1", 30 | "markdown-it-container": "^3.0.0", 31 | "markdown-it-toc": "^1.1.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/components/contextmenu/basic.vue: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /docs/components/menu/event.vue: -------------------------------------------------------------------------------- 1 | 21 | 31 | -------------------------------------------------------------------------------- /docs/components/tooltip/theme.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/colorPicker/predefineColors.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/index.md.55a8372d.js: -------------------------------------------------------------------------------- 1 | import{_ as e,o as t,c as o}from"./app.7f45bc5d.js";const m='{"title":"Home","description":"","frontmatter":{"home":true,"heroImage":"/logo.png","heroAlt":"Logo image","heroText":"X6 \u56FE\u7F16\u8F91\u5F15\u64CE","tagline":"X6 Vue3 Components","actionText":"Get Started","actionLink":"/components/guide","features":[{"title":"\u5FEB\u901F\u4E0A\u624B\uFF0C\u6781\u6613\u5B9A\u5236","details":"\u63D0\u4F9B\u57FA\u4E8E\u4F4E\u5B66\u4E60\u6210\u672C\u7684 SVG/HTML/CSS \u7684\u8282\u70B9\u5B9A\u5236\u80FD\u529B."},{"title":"\u7EC4\u4EF6\u5B8C\u5907\uFF0C\u5F00\u7BB1\u5373\u7528","details":"\u5185\u7F6E 10+ \u56FE\u7F16\u8F91\u573A\u666F\u7684\u914D\u5957\u6269\u5C55\uFF0C\u5982\u6846\u9009\u3001\u5BF9\u9F50\u7EBF\u3001\u5C0F\u5730\u56FE\u7B49."},{"title":"\u7075\u6D3B\uFF0C\u53EF\u6269\u5C55","details":"\u753B\u5E03\u3001\u8282\u70B9\u3001\u8FB9\u3001\u5C5E\u6027\u3001\u5DE5\u5177\u7B49\u5747\u53EF\u4EE5\u901A\u8FC7\u6CE8\u518C\u673A\u5236\u81EA\u7531\u3001\u7075\u6D3B\u6269\u5C55."}],"footer":"MIT Licensed | Copyright \xA9 2021-present"},"headers":[],"relativePath":"index.md"}',a={};function r(n,i,s,c,d,l){return t(),o("div")}var _=e(a,[["render",r]]);export{m as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/index.md.55a8372d.lean.js: -------------------------------------------------------------------------------- 1 | import{_ as e,o as t,c as o}from"./app.7f45bc5d.js";const m='{"title":"Home","description":"","frontmatter":{"home":true,"heroImage":"/logo.png","heroAlt":"Logo image","heroText":"X6 \u56FE\u7F16\u8F91\u5F15\u64CE","tagline":"X6 Vue3 Components","actionText":"Get Started","actionLink":"/components/guide","features":[{"title":"\u5FEB\u901F\u4E0A\u624B\uFF0C\u6781\u6613\u5B9A\u5236","details":"\u63D0\u4F9B\u57FA\u4E8E\u4F4E\u5B66\u4E60\u6210\u672C\u7684 SVG/HTML/CSS \u7684\u8282\u70B9\u5B9A\u5236\u80FD\u529B."},{"title":"\u7EC4\u4EF6\u5B8C\u5907\uFF0C\u5F00\u7BB1\u5373\u7528","details":"\u5185\u7F6E 10+ \u56FE\u7F16\u8F91\u573A\u666F\u7684\u914D\u5957\u6269\u5C55\uFF0C\u5982\u6846\u9009\u3001\u5BF9\u9F50\u7EBF\u3001\u5C0F\u5730\u56FE\u7B49."},{"title":"\u7075\u6D3B\uFF0C\u53EF\u6269\u5C55","details":"\u753B\u5E03\u3001\u8282\u70B9\u3001\u8FB9\u3001\u5C5E\u6027\u3001\u5DE5\u5177\u7B49\u5747\u53EF\u4EE5\u901A\u8FC7\u6CE8\u518C\u673A\u5236\u81EA\u7531\u3001\u7075\u6D3B\u6269\u5C55."}],"footer":"MIT Licensed | Copyright \xA9 2021-present"},"headers":[],"relativePath":"index.md"}',a={};function r(n,i,s,c,d,l){return t(),o("div")}var _=e(a,[["render",r]]);export{m as __pageData,_ as default}; 2 | -------------------------------------------------------------------------------- /docs/components/dropdown/placement.vue: -------------------------------------------------------------------------------- 1 | 11 | 20 | -------------------------------------------------------------------------------- /docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | import { mdPlugin } from './config/plugins' 2 | import nav from './config/nav' 3 | import sidebar from './config/sidebar' 4 | module.exports = { 5 | title: 'X6 Vue3 Components', 6 | description: 'Vue3 components for building x6 editors', 7 | base: '/x6-vue3-components/', 8 | lang: 'en-US', 9 | head: [ 10 | [ 11 | 'link', 12 | { 13 | rel: 'icon', 14 | href: '/x6-vue3-components/favicon.png', 15 | } 16 | ] 17 | ], 18 | themeConfig: { 19 | logo: '/favicon.png', 20 | docsDir: 'docs', 21 | // algolia: { 22 | // apiKey: '8c1a3c4e177b8cbd2c7df09c80bd9fb8', 23 | // appId: 'B45Y19Z2OS', 24 | // indexName: 'x6-vue3-components' 25 | // }, 26 | nav, 27 | sidebar 28 | }, 29 | markdown: { 30 | // options for markdown-it-anchor 31 | anchor: { 32 | permalink: true, 33 | permalinkBefore: true, 34 | permalinkSymbol: '#' 35 | }, 36 | 37 | // options for markdown-it-toc 38 | // toc: { includeLevel: [1, 2] }, 39 | 40 | config: (md) => mdPlugin(md), 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /docs/components/dropdown/location.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/tooltip/placement.vue: -------------------------------------------------------------------------------- 1 | 11 | 20 | -------------------------------------------------------------------------------- /docs/.vitepress/components/Example.vue: -------------------------------------------------------------------------------- 1 | 8 | 23 | 24 | 48 | -------------------------------------------------------------------------------- /docs/components/toolbar/basic.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/toolbar/tooltip.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/toolbar/dropdownArrow.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/menu/submenu.vue: -------------------------------------------------------------------------------- 1 | 28 | 38 | -------------------------------------------------------------------------------- /components/index.js: -------------------------------------------------------------------------------- 1 | import X6ColorPicker from './x6-color-picker'; 2 | import X6ContextMenu from './x6-context-menu'; 3 | import X6Dropdown from './x6-dropdown'; 4 | import X6Menu, { X6SubMenu, X6MenuItem, X6Divider } from './x6-menu'; 5 | import X6Menubar, { X6MenubarItem } from './x6-menubar'; 6 | import X6Scrollbox from './x6-scrollbox'; 7 | import X6SplitBox from './x6-split-box'; 8 | import X6Toolbar, { X6Group, X6Item } from './x6-toolbar'; 9 | import X6Tooltip from './x6-tooltip'; 10 | // import path from 'path'; 11 | 12 | const components = [ 13 | X6ColorPicker, 14 | X6ContextMenu, 15 | X6Dropdown, 16 | X6Menu, 17 | X6SubMenu, 18 | X6MenuItem, 19 | X6Divider, 20 | X6Menubar, 21 | X6MenubarItem, 22 | X6Scrollbox, 23 | X6SplitBox, 24 | X6Toolbar, 25 | X6Group, 26 | X6Item, 27 | X6Tooltip 28 | ] 29 | 30 | // const version = path.resolve('../package.json').version 31 | const install = (app) => { 32 | components.forEach(component => { 33 | app.component(`X6${component.name}`, component); 34 | }); 35 | }; 36 | const _default = { 37 | // version, 38 | install, 39 | }; 40 | 41 | export { 42 | install, 43 | // version, 44 | X6ColorPicker, 45 | X6ContextMenu, 46 | X6Dropdown, 47 | X6Menu, 48 | X6SubMenu, 49 | X6MenuItem, 50 | X6Divider, 51 | X6Menubar, 52 | X6MenubarItem, 53 | X6Scrollbox, 54 | X6SplitBox, 55 | X6Toolbar, 56 | X6Group, 57 | X6Item, 58 | X6Tooltip 59 | } 60 | 61 | export default _default 62 | -------------------------------------------------------------------------------- /docs/components/menu/disabled.vue: -------------------------------------------------------------------------------- 1 | 28 | 38 | -------------------------------------------------------------------------------- /docs/components/colorPicker/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 颜色选择器 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | ## 初始化颜色 13 | 14 | :::demo 初始化颜色为黑色。 15 | 16 | colorPicker/init 17 | 18 | ::: 19 | 20 | ## 禁用颜色选择器 21 | 22 | :::demo `disabled`默认值为`false`。 23 | 24 | colorPicker/disabled 25 | 26 | ::: 27 | 28 | 29 | ## 取消透明度 30 | 31 | :::demo `showAlpha`默认值为`true`。 32 | 33 | colorPicker/hideAlpha 34 | 35 | ::: 36 | 37 | 38 | ## 预设颜色块 39 | 40 | :::demo 41 | 42 | colorPicker/predefineColors 43 | 44 | ::: 45 | 46 | 47 | ## X6ColorPicker 属性 48 | 49 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 50 | |-----------|----------------------------------------------------|------------|---------|---------| 51 | | color | 绑定的色值 | string | - | `#000000` | 52 | | disabled | 是否禁用 | boolean | - | `false` | 53 | | showAlpha | 是否使用透明度 | boolean | - | `false` | 54 | | colorFormat | 颜色类型 | string | `hex, rgb` | `hex` | 55 | | predefineColors | 预设颜色块 | array | - | - | 56 | 57 | ## X6ColorPicker 事件 58 | 59 | | Event Name | Description | Parameters | 60 | | ---------- | --------------------------------------- | -------------------------- | 61 | | change | 颜色修改后触发 | color(修改后的颜色值) | -------------------------------------------------------------------------------- /docs/components/dropdown/theme.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/toolbar/event.vue: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /docs/.vitepress/utils/highlight.js: -------------------------------------------------------------------------------- 1 | // ref https://github.com/vuejs/vitepress/blob/main/src/node/markdown/plugins/highlight.ts 2 | import chalk from 'chalk' 3 | import escapeHtml from 'escape-html' 4 | import prism from 'prismjs' 5 | 6 | // prism is listed as actual dep so it's ok to require 7 | // eslint-disable-next-line @typescript-eslint/no-var-requires 8 | const loadLanguages = require('prismjs/components/index') 9 | 10 | // required to make embedded highlighting work... 11 | loadLanguages(['markup', 'css', 'javascript']) 12 | 13 | function wrap(code, lang) { 14 | if (lang === 'text') { 15 | code = escapeHtml(code) 16 | } 17 | return `
${code}
` 18 | } 19 | 20 | export const highlight = (str, lang) => { 21 | if (!lang) { 22 | return wrap(str, 'text') 23 | } 24 | lang = lang.toLowerCase() 25 | const rawLang = lang 26 | if (lang === 'vue' || lang === 'html') { 27 | lang = 'markup' 28 | } 29 | if (lang === 'md') { 30 | lang = 'markdown' 31 | } 32 | if (lang === 'ts') { 33 | lang = 'typescript' 34 | } 35 | if (lang === 'py') { 36 | lang = 'python' 37 | } 38 | if (!prism.languages[lang]) { 39 | try { 40 | loadLanguages([lang]) 41 | } catch (e) { 42 | // eslint-disable-next-line no-console 43 | console.warn( 44 | chalk.yellow( 45 | `[vitepress] Syntax highlight for language "${lang}" is not supported.` 46 | ) 47 | ) 48 | } 49 | } 50 | if (prism.languages[lang]) { 51 | const code = prism.highlight(str, prism.languages[lang], lang) 52 | return wrap(code, rawLang) 53 | } 54 | return wrap(str, 'text') 55 | } 56 | -------------------------------------------------------------------------------- /docs/components/toolbar/icon.vue: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /docs/.vitepress/config/sidebar.js: -------------------------------------------------------------------------------- 1 | export default { 2 | '/': getDemoSidebar(), 3 | } 4 | 5 | function getDemoSidebar() { 6 | return [ 7 | { 8 | text: "简介", 9 | link: "/components/introduction" 10 | }, 11 | { 12 | text: "开发指南", 13 | link: "/components/guide" 14 | }, 15 | { 16 | text: "组件", 17 | children: [ 18 | // { 19 | // text: "例子", 20 | // link: "/components/button/" 21 | // }, 22 | { 23 | text: "X6Menu", 24 | link: "/components/menu/" 25 | }, 26 | { 27 | text: "X6Dropdown", 28 | link: "/components/dropdown/" 29 | }, 30 | { 31 | text: "X6ContextMenu", 32 | link: "/components/contextmenu/" 33 | }, 34 | { 35 | text: "X6Menubar", 36 | link: "/components/menubar/" 37 | }, 38 | { 39 | text: "X6Toolbar", 40 | link: "/components/toolbar/" 41 | }, 42 | { 43 | text: "X6SplitBox", 44 | link: "/components/splitbox/" 45 | }, 46 | { 47 | text: "X6Scrollbox", 48 | link: "/components/scrollbox/" 49 | }, 50 | { 51 | text: "X6Tooltip", 52 | link: "/components/tooltip/" 53 | }, 54 | { 55 | text: "X6ColorPicker", 56 | link: "/components/colorPicker/" 57 | } 58 | ] 59 | } 60 | ] 61 | } -------------------------------------------------------------------------------- /docs/components/menubar/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 菜单栏 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | :::tip 13 | 14 | `X6Menubar`组件的子组件有`X6MenubarItem`、`X6Menu`、`X6MenuItem`、`X6Divider` 15 | 16 | ::: 17 | 18 | ## 基础菜单栏 19 | 20 | :::demo 21 | 22 | menubar/basic 23 | 24 | ::: 25 | 26 | ## X6Menubar 属性 27 | 28 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 29 | |----------------------|--------------------------|--------------------------------|--------------|--------------| 30 | | className | 自定义的样式名 | string | - | - | 31 | 32 | ## X6Menubar 插槽 33 | | 插槽名 | 说明 | 子标签 | 34 | |------------------|--------------------------|-----------------------------------------------| 35 | | - | 菜单栏文本内容 | - | 36 | | extra | 菜单栏扩展内容 | - | 37 | 38 | 39 | ## X6MenubarItem 属性 40 | 41 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 42 | |----------------------|--------------------------|--------------------------------|--------------|--------------| 43 | | text | 菜单项文本 | string | - | - | 44 | | hidden | 是否隐藏 | boolean | - | `false` | 45 | 46 | 47 | ## X6MenubarItem 插槽 48 | | 插槽名 | 说明 | 子标签 | 49 | |------------------|--------------------------|-----------------------------------------------| 50 | | - | 菜单栏项内容 | - | 51 | | extra | 菜单栏扩展内容 | - | -------------------------------------------------------------------------------- /docs/components/contextmenu/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 上下文菜单 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | ## 基础使用 13 | 14 | :::demo 右键触发。 15 | 16 | contextmenu/basic 17 | 18 | ::: 19 | 20 | ## X6ContextMenu 属性 21 | 22 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 23 | |------------------|--------------------------|-----------------------------------------------|---------|---------| 24 | | className | 自定义的样式名 | string | - | - | 25 | | transitionName | transition animation类型 | string | `shift-away, shift-toward, perspective, fade, scale` | `shift-away` | 26 | | placement | 下拉菜单的位置 | string | `top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, left-end, auto, auto-start, auto-end` | - | 27 | | mouseEnterDelay | 鼠标移入后延时多少才显示下拉菜单,单位:秒 | number | - | `0.15` | 28 | | mouseLeaveDelay | 鼠标移出后延时多少才隐藏下拉菜单,单位:秒 | number | - | `0.1` | 29 | | tAppendTo | 下拉菜单渲染位置 | string, function | `() => document.body, parent` | `() => document.body` | 30 | | tTheme | 下拉菜单渲染主题 | string | `dark、light、light-border` | `light-border` | 31 | | tAnimateFill | 下拉菜单提示箭头 | boolean | - | `false` | 32 | 33 | ## X6ContextMenu 插槽 34 | 35 | | 插槽名 | 说明 | 子标签 | 36 | |------------------|--------------------------|-----------------------------------------------| 37 | | — | 渲染文本 | - | 38 | | menu | 菜单内容 | - | -------------------------------------------------------------------------------- /docs/components/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 简介 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建流程图、DAG 图、ER 图等图应用。 8 | 9 | 如果你还没有使用过 X6, 建议通过 [快速上手](https://x6.antv.vision/zh/docs/tutorial/getting-started/) 抢先体验 X6 的魅力。 10 | 11 | [![MIT License](https://img.shields.io/badge/license-MIT_License-green.svg?style=flat-square)](https://github.com/antvis/x6/blob/master/LICENSE) 12 | [![Language](https://img.shields.io/badge/language-typescript-blue.svg?style=flat-square)](https://www.typescriptlang.org) 13 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/antvis/x6/pulls) 14 | 15 | [![build](https://img.shields.io/travis/antvis/x6.svg?style=flat-square)](https://travis-ci.org/antvis/x6) 16 | [![coverage](https://img.shields.io/coveralls/antvis/x6/master.svg?style=flat-square)](https://coveralls.io/github/antvis/x6) 17 | [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/antvis/x6.svg?logo=lgtm&style=flat-square)](https://lgtm.com/projects/g/antvis/x6/context:javascript) 18 | 19 | [![NPM Package](https://img.shields.io/npm/v/@antv/x6.svg?style=flat-square)](https://www.npmjs.com/package/@antv/x6) 20 | [![NPM Downloads](https://img.shields.io/npm/dm/@antv/x6.svg?style=flat-square)](https://www.npmjs.com/package/@antv/x6) 21 | [![NPM Dependencies](https://img.shields.io/david/antvis/x6?path=packages%2Fx6&style=flat-square)](https://www.npmjs.com/package/@antv/x6) 22 | 23 | ## ✨ 特性 24 | 25 | - 🌱 极易定制:支持使用 SVG/HTML/React/Vue 定制节点样式和交互; 26 | - 🚀 开箱即用:内置 10+ 图编辑配套扩展,如框选、对齐线、小地图等; 27 | - 🧲 数据驱动:基于 MVC 架构,用户更加专注于数据逻辑和业务逻辑; 28 | - 💯 事件驱动:可以监听图表内发生的任何事件。 29 | 30 | ## 🍉 使用文档 31 | 本文章提供了x6适配Vue3的组件,详细如下 32 | - [开发指南](guide) 33 | - [X6Menu](./menu/) 菜单 34 | - [X6Dropdown](./dropdown/) 下拉菜单 35 | - [X6ContextMenu](./contextmenu/) 上下文菜单 36 | - [X6Menubar](./menubar/) 菜单栏 37 | - [X6Toolbar](./toolbar/) 工具栏 38 | - [X6SplitBox](./splitbox/) 分割容器 39 | - [X6ScrollBox](./scrollbox/) 自定义滚动条的容器 40 | - [X6Tooltip](./tooltip/) 提示 41 | - [X6ColorPicker](./colorPicker/) 颜色选择器 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # x6-vue3-components 开发指南 2 | 3 | 搭建一个复杂的图编辑应用还需要用到 Menubar、Toolbar、Dropdown、ContextMenu、Splitbox 等 UI 组件,我们在 [x6-vue3-components](https://www.npmjs.com/package/x6-vue3-components) 中提供了一些这样的 Vue3 组件,可以搭配 [elemnt-plus](https://element-plus.gitee.io/) 使用。 4 | 5 | ## 安装 6 | 7 | ```shell 8 | # npm 9 | $ npm install x6-vue3-components --save 10 | 11 | # yarn 12 | $ yarn add x6-vue3-components 13 | ``` 14 | 15 | 16 | 17 | ## 使用 18 | 19 | 引入需要的组件和对应的样式: 20 | 21 | ```js 22 | import { X6Menu } from 'x6-vue3-components' 23 | // css 24 | import 'x6-vue3-components/lib/x6-vue3-components.css' 25 | // or min css 26 | import 'x6-vue3-components/lib/x6-vue3-components.min.css' 27 | ``` 28 | 29 | 我们强烈建议使用 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 插件来自动引用组件样式,在 `babel.config.js` 或 babel-loader 中添加如下配置: 30 | 31 | ```js 32 | { 33 | plugins: [ 34 | [ 35 | "import", 36 | { 37 | libraryName: "x6-vue3-components", 38 | libraryDirectory: "lib", 39 | style: (name) => { 40 | const libDirIndex = name.lastIndexOf('/') 41 | const libDir = name.substring(0, libDirIndex) 42 | const fileName = name.substr(libDirIndex + 1) 43 | return `${libDir}/${fileName}.css`; 44 | } 45 | } 46 | ] 47 | ] 48 | } 49 | ``` 50 | 51 | 这样我们引入组件时就会自动引入对应的样式: 52 | 53 | ```js 54 | import { X6Menu } from 'x6-vue3-components' 55 | ``` 56 | 57 | 如果是使用引入后报错:`[Vue warn]: Invalid VNode type: Symbol(Comment) (symbol)`。请参考该[issues](https://github.com/vuejs/core/issues/2064#issuecomment-797365133)。具体修改如下: 58 | 59 | With webpack and Vue CLI in `vue.config.js` 60 | ```js 61 | const path = require('path') 62 | 63 | module.exports = { 64 | configureWebpack: { 65 | resolve: { 66 | symlinks: false, 67 | alias: { 68 | vue: path.resolve('./node_modules/vue') 69 | } 70 | } 71 | } 72 | } 73 | ``` 74 | 75 | With Vite in `vite.config.js` 76 | ```js 77 | export default { 78 | resolve: { 79 | dedupe: ['vue'] 80 | } 81 | } 82 | ``` -------------------------------------------------------------------------------- /components/x6-context-menu/ContextMenu.vue: -------------------------------------------------------------------------------- 1 | 9 | 65 | -------------------------------------------------------------------------------- /components/x6-toolbar/Toolbar.vue: -------------------------------------------------------------------------------- 1 | 14 | 68 | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/Home.29e71739.js: -------------------------------------------------------------------------------- 1 | import{_ as m,i as h,j as y,k as i,u as e,o,c as a,d as _,l as F,m as r,t as l,f as g,N as x,F as I,g as L,r as b,a as d,p as k}from"./app.7f45bc5d.js";const A={key:0,class:"home-hero"},B={key:0,class:"figure"},C=["src","alt"],N={key:1,id:"main-title",class:"title"},w={key:2,class:"tagline"},V=h({setup(p){const{site:s,frontmatter:t}=y(),c=i(()=>{const{heroImage:n,heroText:u,tagline:$,actionLink:H,actionText:T}=t.value;return n||u||$||H&&T}),v=i(()=>t.value.heroText||s.value.title),f=i(()=>t.value.tagline||s.value.description);return(n,u)=>e(c)?(o(),a("header",A,[e(t).heroImage?(o(),a("figure",B,[_("img",{class:"image",src:e(F)(e(t).heroImage),alt:e(t).heroAlt},null,8,C)])):r("",!0),e(v)?(o(),a("h1",N,l(e(v)),1)):r("",!0),e(f)?(o(),a("p",w,l(e(f)),1)):r("",!0),e(t).actionLink&&e(t).actionText?(o(),g(x,{key:3,item:{link:e(t).actionLink,text:e(t).actionText},class:"action"},null,8,["item"])):r("",!0),e(t).altActionLink&&e(t).altActionText?(o(),g(x,{key:4,item:{link:e(t).altActionLink,text:e(t).altActionText},class:"action alt"},null,8,["item"])):r("",!0)])):r("",!0)}});var D=m(V,[["__scopeId","data-v-5d8b683d"]]);const S={key:0,class:"home-features"},j={class:"wrapper"},E={class:"container"},q={class:"features"},z={key:0,class:"title"},G={key:1,class:"details"},J=h({setup(p){const{frontmatter:s}=y(),t=i(()=>s.value.features&&s.value.features.length>0),c=i(()=>s.value.features?s.value.features:[]);return(v,f)=>e(t)?(o(),a("div",S,[_("div",j,[_("div",E,[_("div",q,[(o(!0),a(I,null,L(e(c),(n,u)=>(o(),a("section",{key:u,class:"feature"},[n.title?(o(),a("h2",z,l(n.title),1)):r("",!0),n.details?(o(),a("p",G,l(n.details),1)):r("",!0)]))),128))])])])])):r("",!0)}});var K=m(J,[["__scopeId","data-v-245bde66"]]);const M={key:0,class:"footer"},O={class:"container"},P={class:"text"},Q=h({setup(p){const{frontmatter:s}=y();return(t,c)=>e(s).footer?(o(),a("footer",M,[_("div",O,[_("p",P,l(e(s).footer),1)])])):r("",!0)}});var R=m(Q,[["__scopeId","data-v-bff49316"]]);const U={class:"home","aria-labelledby":"main-title"},W={class:"home-content"},X=h({setup(p){return(s,t)=>{const c=b("Content");return o(),a("main",U,[d(D),k(s.$slots,"hero",{},void 0,!0),d(K),_("div",W,[d(c)]),k(s.$slots,"features",{},void 0,!0),d(R),k(s.$slots,"footer",{},void 0,!0)])}}});var Z=m(X,[["__scopeId","data-v-8382b818"]]);export{Z as default}; 2 | -------------------------------------------------------------------------------- /components/overlayscrollbars-vue3/OverlayScrollbarsComponent.vue: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "x6-vue3-components", 3 | "version": "1.1.3", 4 | "description": "X6 Components for Vue3.", 5 | "keywords": [ 6 | "antvx6", 7 | "components", 8 | "vue3" 9 | ], 10 | "files": [ 11 | "components", 12 | "lib" 13 | ], 14 | "homepage": "https://daizhigitee.gitee.io/x6-vue3-components/", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/xiaodai123/x6-vue3-components" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/xiaodai123/x6-vue3-components/issues" 21 | }, 22 | "main": "lib/x6-vue3-components.min.js", 23 | "module": "lib/x6-vue3-components.esm.min.js", 24 | "author": "daizhi", 25 | "license": "MIT", 26 | "devDependencies": { 27 | "@babel/cli": "^7.17.0", 28 | "@babel/core": "^7.17.2", 29 | "@babel/preset-env": "^7.16.11", 30 | "@babel/runtime": "^7.17.2", 31 | "@babel/runtime-corejs3": "^7.17.2", 32 | "@rollup/plugin-babel": "^5.3.0", 33 | "@rollup/plugin-commonjs": "^21.0.1", 34 | "@rollup/plugin-node-resolve": "^13.1.3", 35 | "@rollup/plugin-replace": "^3.1.0", 36 | "@vue/compiler-sfc": "^3.0.0-rc.5", 37 | "autoprefixer": "^10.4.2", 38 | "chalk": "^2.4.2", 39 | "gulp": "^4.0.2", 40 | "postcss": "^8.4.6", 41 | "rollup": "^2.67.2", 42 | "rollup-plugin-scss": "^3.0.0", 43 | "rollup-plugin-terser": "^7.0.2", 44 | "rollup-plugin-vue": "^6.0.0-beta.10", 45 | "sass": "^1.49.7", 46 | "shelljs": "^0.7.7" 47 | }, 48 | "dependencies": { 49 | "add-dom-event-listener": "^1.1.0", 50 | "clamp": "^1.0.1", 51 | "hotkeys-js": "^3.8.7", 52 | "overlayscrollbars": "^1.13.1", 53 | "tippy.js": "^6.3.7", 54 | "tippy.vue": "^3.1.2", 55 | "vue": "^3.2.29" 56 | }, 57 | "peerDependencies": { 58 | "add-dom-event-listener": "^1.1.0", 59 | "clamp": "^1.0.1", 60 | "hotkeys-js": "^3.8.7", 61 | "overlayscrollbars": "^1.13.1", 62 | "tippy.js": "^6.3.7", 63 | "tippy.vue": "^3.1.2" 64 | }, 65 | "scripts": { 66 | "setup": "npm i && cd example && npm i && cd ..", 67 | "build": "node build.js", 68 | "example": "cd example && npm run serve", 69 | "build-example": "cd example && npm run build", 70 | "test": "echo \"Error: no test specified\" && exit 1" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /docs/components/menu/hotKey.vue: -------------------------------------------------------------------------------- 1 | 47 | 63 | -------------------------------------------------------------------------------- /docs/components/scrollbox/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 自定义滚动条的容器 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | :::tip 13 | 14 | 该滚动条依赖[OverlayScrollbars](https://kingsora.github.io/OverlayScrollbars/#!documentation/options),具体配置请参考官网 15 | 16 | ::: 17 | 18 | ## 元素调整大小 19 | 20 | :::demo `resize`有`none, both, horizontal, vertical`。 21 | 22 | scrollbox/resize 23 | 24 | ::: 25 | 26 | ## 溢出后行为 27 | 28 | :::demo 29 | 30 | scrollbox/xy 31 | 32 | ::: 33 | 34 | 35 | ## 滚动条的行为 36 | 37 | :::demo 38 | 39 | scrollbox/scroll 40 | 41 | ::: 42 | 43 | 44 | ## X6Scrollbox 属性 45 | 46 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 47 | |------------------|--------------------------|-----------------------------------------------|---------|---------| 48 | | className | 自定义的样式名 | string | - | `os-theme-dark` | 49 | | resize | 宿主元素的调整大小行为 | string | `none, both, horizontal, vertical` | `none` | 50 | | sizeAutoCapable | 宿主元素是否能够“自动”大小 | boolean | | `true` | 51 | | overflowBehaviorX | 定义如何处理X轴的溢出 | string | `hidden, scroll, visible-hidden, visible-scroll` | `scroll` | 52 | | overflowBehaviorY | 定义如何处理Y轴的溢出 | string | `hidden, scroll, visible-hidden, visible-scroll` | `scroll` | 53 | | scrollbarsVisibility | 滚动条是否可见 | string | `visible, hidden, auto` | `auto` | 54 | | scrollbarsAutoHide | 滚动条是否自动隐藏 | string | `never, scroll, leave, move | `never` | 55 | | scrollbarsAutoHideDelay | 滚动条隐藏延迟时间,单位:毫秒 | number | - | `800` | 56 | | initializedCb | 滚动条初始化钩子 | function | - | - | 57 | | destroyedCb | 滚动条销毁钩子 | function | - | - | 58 | | scrollStartCb | 滚动条滚动开始钩子,参数为eventArgs | function | - | - | 59 | | scrollCb | 滚动条滚动钩子,参数为eventArgs | function | - | - | 60 | | scrollStopCb | 滚动条滚动停止钩子,参数为eventArgs | function | - | - | 61 | 62 | 63 | 64 | ## X6Scrollbox 插槽 65 | | 插槽名 | 说明 | 子标签 | 66 | |------------------|--------------------------|-----------------------------------------------| 67 | | - | 滚动条内容 | - | -------------------------------------------------------------------------------- /components/x6-menubar/Menubar.vue: -------------------------------------------------------------------------------- 1 | 14 | 79 | -------------------------------------------------------------------------------- /docs/components/tooltip/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 提示 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | ## Hover触发 13 | 14 | :::demo `trigger`为`mouseenter focus`。 15 | 16 | tooltip/hover 17 | 18 | ::: 19 | 20 | ## 鼠标点击触发 21 | 22 | :::demo `trigger`为`click`。 23 | 24 | tooltip/click 25 | 26 | ::: 27 | 28 | ## 下拉菜单的位置 29 | 30 | :::demo `placement`有`top`, `top-start`, `top-end`, `right`, `right-start`, `right-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `auto`, `auto-start`, `auto-end`。 31 | 32 | tooltip/placement 33 | 34 | ::: 35 | 36 | ## 渲染位置 37 | 38 | :::demo 渲染位置有`body`, `parent`。 39 | 40 | tooltip/location 41 | 42 | ::: 43 | 44 | ## 主题 45 | 46 | :::demo 主题有`dark`, `light`, `light-border`。 47 | 48 | tooltip/theme 49 | 50 | ::: 51 | 52 | 53 | ## X6Tooltip 属性 54 | 55 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 56 | |------------------|--------------------------|-----------------------------------------------|---------|---------| 57 | | trigger | 触发行为 | string | `contextmenu, mouseenter focus, click, focusin, mouseenter click, manual` | `mouseenter focus` | 58 | | animation | transition animation类型 | string | `shift-away, shift-toward, perspective, fade, scale` | `fade` | 59 | | placement | 提示的位置 | string | `top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, left-end, auto, auto-start, auto-end` | `top` | 60 | | delay | 鼠标移入后延时多少才显示提示,鼠标移出后延时多少才隐藏提示,单位:秒 | array | - | - | 61 | | hideOnClick | 点击其他位置隐藏提示内容,trigger为click时设置该值显示更合适 | boolean | - | `false` | 62 | | tAppendTo | 提示渲染位置 | string, function | `() => document.body, parent` | `() => document.body` | 63 | | tTheme | 提示渲染主题 | string | `dark、light、light-border` | `light` | 64 | | tAnimateFill | 提示提示箭头 | boolean | - | `false` | 65 | | interactive | 提示是否可以停留鼠标 | boolean | - | `false` | 66 | 67 | 68 | ## X6Tooltip 插槽 69 | | 插槽名 | 说明 | 子标签 | 70 | |------------------|--------------------------|-----------------------------------------------| 71 | | - | 提示内容 | - | -------------------------------------------------------------------------------- /docs/components/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 开发指南 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | 搭建一个复杂的图编辑应用还需要用到 X6Menubar、X6Toolbar、X6Dropdown、X6ContextMenu、X6Splitbox 等 UI 组件,我们在 [x6-vue3-components](https://www.npmjs.com/package/x6-vue3-components) 中提供了一些这样的 Vue3 组件,可以搭配 [elemnt-plus](https://element-plus.gitee.io/) 使用。 8 | 9 | ## 安装 10 | 11 | ```shell 12 | # npm 13 | $ npm install x6-vue3-components --save 14 | 15 | # yarn 16 | $ yarn add x6-vue3-components 17 | ``` 18 | 19 | 20 | 21 | ## 使用 22 | 23 | 引入需要的组件和对应的样式: 24 | 25 | ```js 26 | import { X6Menu } from 'x6-vue3-components' 27 | // css 28 | import 'x6-vue3-components/lib/x6-vue3-components.css' 29 | // or min css 30 | import 'x6-vue3-components/lib/x6-vue3-components.min.css' 31 | ``` 32 | 33 | 我们强烈建议使用 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 插件来自动引用组件样式,在 `babel.config.js` 或 babel-loader 中添加如下配置: 34 | 35 | ```js 36 | { 37 | plugins: [ 38 | [ 39 | "import", 40 | { 41 | libraryName: "x6-vue3-components", 42 | libraryDirectory: "lib", 43 | style: (name) => { 44 | const libDirIndex = name.lastIndexOf('/') 45 | const libDir = name.substring(0, libDirIndex) 46 | const fileName = name.substr(libDirIndex + 1) 47 | return `${libDir}/${fileName}.css`; 48 | } 49 | } 50 | ] 51 | ] 52 | } 53 | ``` 54 | 55 | 这样我们引入组件时就会自动引入对应的样式: 56 | 57 | ```js 58 | import { X6Menu } from 'x6-vue3-components' 59 | ``` 60 | 61 | 如果是使用引入后报错:`[Vue warn]: Invalid VNode type: Symbol(Comment) (symbol)`。请参考该[issues](https://github.com/vuejs/core/issues/2064#issuecomment-797365133)。具体修改如下: 62 | 63 | With webpack and Vue CLI in `vue.config.js` 64 | ```js 65 | const path = require('path') 66 | 67 | module.exports = { 68 | configureWebpack: { 69 | resolve: { 70 | symlinks: false, 71 | alias: { 72 | vue: path.resolve('./node_modules/vue') 73 | } 74 | } 75 | } 76 | } 77 | ``` 78 | 79 | With Vite in `vite.config.js` 80 | ```js 81 | export default { 82 | resolve: { 83 | dedupe: ['vue'] 84 | } 85 | } 86 | ``` 87 | 88 | ## 组件 89 | 90 | 点击下面链接查看每个组件的使用文档。 91 | 92 | 93 | 94 | - [X6Menu](./menu/) 菜单 95 | - [X6Dropdown](./dropdown/) 下拉菜单 96 | - [X6ContextMenu](./contextmenu/) 上下文菜单 97 | - [X6Menubar](./menubar/) 菜单栏 98 | - [X6Toolbar](./toolbar/) 工具栏 99 | - [X6SplitBox](./splitbox/) 分割容器 100 | - [X6ScrollBox](./scrollbox/) 自定义滚动条的容器 101 | - [X6Tooltip](./tooltip/) 提示 102 | - [X6ColorPicker](./colorPicker/) 颜色选择器 -------------------------------------------------------------------------------- /components/x6-split-box/Box.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /docs/components/dropdown/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 下拉菜单 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | ## Hover触发 13 | 14 | :::demo `trigger`为`mouseenter focus`。 15 | 16 | dropdown/hover 17 | 18 | ::: 19 | 20 | ## 鼠标右键触发 21 | 22 | :::demo `trigger`为`contextmenu`。 23 | 24 | dropdown/contextMenu 25 | 26 | ::: 27 | 28 | ## 下拉菜单的位置 29 | 30 | :::demo `placement`有`top`, `top-start`, `top-end`, `right`, `right-start`, `right-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `auto`, `auto-start`, `auto-end`。 31 | 32 | dropdown/placement 33 | 34 | ::: 35 | 36 | ## 渲染位置 37 | 38 | :::demo 渲染位置有`body`, `parent`。 39 | 40 | dropdown/location 41 | 42 | ::: 43 | 44 | ## 主题 45 | 46 | :::demo 主题有`dark`, `light`, `light-border`。 47 | 48 | dropdown/theme 49 | 50 | ::: 51 | 52 | ## X6Dropdown 属性 53 | 54 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 55 | |------------------|--------------------------|-----------------------------------------------|---------|---------| 56 | | className | 自定义的样式名 | string | - | - | 57 | | trigger | 触发行为 | string | `contextmenu, mouseenter focus, click, focusin, mouseenter click, manual` | `click` | 58 | | transitionName | transition animation类型 | string | `shift-away, shift-toward, perspective, fade, scale` | `shift-away` | 59 | | placement | 下拉菜单的位置 | string | `top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, left-end, auto, auto-start, auto-end` | `bottom` | 60 | | mouseEnterDelay | 鼠标移入后延时多少才显示下拉菜单,单位:秒 | number | - | `0.15` | 61 | | mouseLeaveDelay | 鼠标移出后延时多少才隐藏下拉菜单,单位:秒 | number | - | `0.1` | 62 | | tAppendTo | 下拉菜单渲染位置 | string, function | `() => document.body, parent` | `() => document.body` | 63 | | tTheme | 下拉菜单渲染主题 | string | `dark、light、light-border` | `light` | 64 | | tAnimateFill | 下拉菜单提示箭头 | boolean | - | `false` | 65 | 66 | ## X6Dropdown 插槽 67 | 68 | | 插槽名 | 说明 | 子标签 | 69 | |------------------|--------------------------|-----------------------------------------------| 70 | | — | 渲染文本 | - | 71 | | visible | 下拉菜单内容 | - | -------------------------------------------------------------------------------- /docs/.vitepress/config/plugins.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import fs from 'fs' 3 | import MarkdownIt from 'markdown-it' 4 | import mdContainer from 'markdown-it-container' 5 | import { highlight } from '../utils/highlight' 6 | import { docRoot } from '../utils/paths' 7 | 8 | const localMd = MarkdownIt() 9 | const scriptSetupRE = /<\s*script[^>]*\bsetup\b[^>]*/ 10 | 11 | 12 | export const mdPlugin = (md) => { 13 | md.use(mdContainer, 'demo', { 14 | validate(params) { 15 | return !!params.trim().match(/^demo\s*(.*)$/) 16 | }, 17 | 18 | render(tokens, idx) { 19 | const data = md.__data 20 | const hoistedTags = data.hoistedTags || (data.hoistedTags = []) 21 | 22 | const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/) 23 | if (tokens[idx].nesting === 1 /* means the tag is opening */) { 24 | const description = m && m.length > 1 ? m[1] : '' 25 | const sourceFileToken = tokens[idx + 2] 26 | let source = '' 27 | let sourceFile = '' 28 | if (sourceFileToken.children) { 29 | sourceFile = sourceFileToken.children[0].content 30 | } 31 | 32 | if (sourceFileToken.type === 'inline') { 33 | source = fs.readFileSync( 34 | path.resolve(docRoot, 'components', `${sourceFile}.vue`), 35 | 'utf-8' 36 | ) 37 | const existingScriptIndex = hoistedTags.findIndex((tag) => 38 | scriptSetupRE.test(tag) 39 | ) 40 | if (existingScriptIndex === -1) { 41 | hoistedTags.push(` 42 | `) 47 | } 48 | } 49 | if (!source) throw new Error(`Incorrect source file: ${sourceFile}`) 50 | 51 | return `` 56 | } else { 57 | return '' 58 | } 59 | } 60 | }) 61 | 62 | md.use(mdContainer, 'doc-toc', { 63 | validate(params) { 64 | return !!params.trim().match(/^doc-toc\s*(.*)$/) 65 | }, 66 | 67 | render(tokens, idx) { 68 | return '' 69 | } 70 | }) 71 | } 72 | -------------------------------------------------------------------------------- /components/x6-split-box/Resizer.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /docs/components/splitbox/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 分割容器 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | ## 简单分割 13 | 14 | :::demo X6SplitBox有主次两个Box。 15 | 16 | splitbox/basic 17 | 18 | ::: 19 | 20 | ## 不显示分割线 21 | 22 | :::demo 23 | 24 | splitbox/noDivider 25 | 26 | ::: 27 | 28 | ## 复杂分割 29 | 30 | :::demo 31 | 32 | splitbox/complex 33 | 34 | ::: 35 | 36 | 37 | ## X6SplitBox 属性 38 | 39 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 40 | |----------------------|--------------------------|--------------------------------|--------------|--------------| 41 | | split | 拆分方向 | string | `vertical、horizontal` | `vertical` | 42 | | resizable | 是否可以调整面板大小 | boolean | - | `true` | 43 | | primary | 主面板 | string | `first、second` | `first` | 44 | | size | 主面板大小 | number、string | - | - | 45 | | defaultSize | 主面板默认大小 | number、string | - | `25%` | 46 | | minSize | 主面板最小大小 | number | - | - | 47 | | maxSize | 主面板最大大小 | number | - | - | 48 | | step | 调整大小的步长 | number | - | - | 49 | | styleProperties | 组件样式 | CSSProperties | - | - | 50 | | boxStyle | 面板样式 | CSSProperties | - | - | 51 | | primaryBoxStyle | 主面板样式 | CSSProperties | - | - | 52 | | secondBoxStyle | 次面板样式 | CSSProperties | - | - | 53 | | resizerStyle | 分割条样式 | CSSProperties | - | - | 54 | | onResizeStart | 开始调整大小时的回调函数 | () => void | - | - | 55 | | onResizeEnd | 调整大小结束时的回调函数 | (newSize) => void | - | - | 56 | | onResizing | 调整大小过程中的回调函数 | (newSize) => void | - | - | 57 | | onResizerClick | 单击分隔条的回调函数 | () => void | - | - | 58 | | onResizerDoubleClick | 双击分隔条的回调函数 | () => void | - | - | 59 | 60 | ## X6SplitBox 插槽 61 | | 插槽名 | 说明 | 子标签 | 62 | |------------------|--------------------------|-----------------------------------------------| 63 | | first | 第一个Box内容 | - | 64 | | second | 第二个Box内容 | - | -------------------------------------------------------------------------------- /components/x6-menu/Menu.vue: -------------------------------------------------------------------------------- 1 | 6 | 97 | -------------------------------------------------------------------------------- /components/theme-chalk/x6-menubar.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './x6-menu.scss'; 3 | 4 | $menubar-prefix-cls: '#{$x6-prefix}-menubar'; 5 | 6 | $menubar-menu-item-color: #616161; 7 | $menubar-menu-item-hover-color: #212121; 8 | $menubar-menu-item-hover-bg: rgba(255, 255, 255, 0); 9 | $menubar-menu-item-active-color: #212121; 10 | $menubar-menu-item-active-bg: #ffffff; 11 | $menubar-item-shadow: 0 0 6px rgba(0, 0, 0, 0.2); 12 | 13 | .#{$menubar-prefix-cls} { 14 | $self: &; 15 | display: flex; 16 | flex: 1; 17 | flex-direction: row; 18 | margin: 0; 19 | padding: 0; 20 | height: 30px; 21 | line-height: 30px; 22 | 23 | &-content { 24 | display: flex; 25 | flex: 1 1; 26 | flex-direction: row; 27 | justify-content: space-between; 28 | } 29 | 30 | &-content-inner, 31 | &-content-extras, 32 | &-item, 33 | &-item-text { 34 | position: relative; 35 | display: inline-flex; 36 | flex-direction: row; 37 | } 38 | 39 | &-content-extras { 40 | align-content: center; 41 | align-items: center; 42 | } 43 | 44 | &-item { 45 | position: relative; 46 | } 47 | 48 | &-item-hidden { 49 | display: none; 50 | } 51 | 52 | &-item-text { 53 | position: relative; 54 | align-content: center; 55 | align-items: center; 56 | padding: 0 10px; 57 | color: $menubar-menu-item-color; 58 | font-size: 13px; 59 | cursor: pointer; 60 | user-select: none; 61 | 62 | &:hover { 63 | color: $menubar-menu-item-hover-color; 64 | background: $menubar-menu-item-hover-bg; 65 | } 66 | } 67 | 68 | &-item-text-active, 69 | &-item-text-active:hover { 70 | color: $menubar-menu-item-active-color; 71 | background: $menubar-menu-item-active-bg; 72 | box-shadow: $menubar-item-shadow; 73 | 74 | &::after { 75 | position: absolute; 76 | bottom: 2px; 77 | left: 0; 78 | z-index: 10000; 79 | width: 100%; 80 | height: 6px; 81 | background: $menubar-menu-item-active-bg; 82 | content: ' '; 83 | } 84 | } 85 | 86 | &-item-dropdown { 87 | position: absolute; 88 | top: 28px; 89 | left: 0; 90 | z-index: 9999; 91 | min-height: 34px; 92 | transform: translateY(-10px); 93 | visibility: hidden; 94 | opacity: 0; 95 | transition: all 0.25s cubic-bezier(0.3, 1.2, 0.2, 1); 96 | box-shadow: 0 2px 10px rgb(0 0 0 / 12%); 97 | 98 | .#{$menu-prefix-cls} { 99 | min-width: 240px; 100 | } 101 | 102 | & > .#{$menu-prefix-cls} { 103 | border-radius: 0 4px 4px 4px; 104 | } 105 | 106 | .#{$menu-prefix-cls}-submenu-menu { 107 | border-radius: 4px; 108 | } 109 | } 110 | 111 | &-item-active > &-item-dropdown { 112 | transform: translateY(0); 113 | visibility: visible; 114 | opacity: 1; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /docs/components/splitbox/complex.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vitepress/components/TocContentNav.vue: -------------------------------------------------------------------------------- 1 | 27 | 46 | -------------------------------------------------------------------------------- /components/x6-menu/SubMenu.vue: -------------------------------------------------------------------------------- 1 | 35 | 100 | -------------------------------------------------------------------------------- /components/x6-tooltip/Tooltip.vue: -------------------------------------------------------------------------------- 1 | 6 | 113 | -------------------------------------------------------------------------------- /components/x6-dropdown/Dropdown.vue: -------------------------------------------------------------------------------- 1 | 9 | 99 | -------------------------------------------------------------------------------- /components/util/dom/MouseMoveTracker.js: -------------------------------------------------------------------------------- 1 | import addEventListener from 'add-dom-event-listener' 2 | import { requestAnimationFrame, cancelAnimationFrame } from './animationFrame' 3 | 4 | export class MouseMoveTracker { 5 | elem = null; 6 | 7 | clientX = 0; 8 | 9 | clientY = 0; 10 | 11 | deltaX = 0; 12 | 13 | deltaY = 0; 14 | 15 | dragging = false; 16 | 17 | captured = false; 18 | 19 | animationFrameID = null; 20 | 21 | removeMouseMoveEvent = () => {}; 22 | 23 | removeMouseUpEvent = () => {}; 24 | 25 | onMouseMoveCallback = (deltaX, deltaY, pos) => {}; 26 | 27 | onMouseMoveEndCallback = (cancel = false) => {}; 28 | 29 | constructor(options) { 30 | this.elem = options.elem || document.documentElement 31 | this.onMouseMoveCallback = options.onMouseMove 32 | this.onMouseMoveEndCallback = options.onMouseMoveEnd 33 | this.animationFrameID = null 34 | } 35 | 36 | capture(e) { 37 | if (!this.captured) { 38 | this.removeMouseMoveEvent = addEventListener( 39 | this.elem, 40 | 'mousemove', 41 | this.onMouseMove, 42 | ).remove 43 | this.removeMouseUpEvent = addEventListener( 44 | this.elem, 45 | 'mouseup', 46 | this.onMouseUp, 47 | ).remove 48 | } 49 | 50 | this.captured = true 51 | 52 | if (!this.dragging) { 53 | this.clientX = e.clientX 54 | this.clientY = e.clientY 55 | this.deltaX = 0 56 | this.deltaY = 0 57 | this.dragging = true 58 | } 59 | 60 | e.preventDefault() 61 | } 62 | 63 | release() { 64 | if (this.captured) { 65 | if (this.removeMouseMoveEvent != null) { 66 | this.removeMouseMoveEvent() 67 | this.removeMouseMoveEvent = null 68 | } 69 | 70 | if (this.removeMouseUpEvent != null) { 71 | this.removeMouseUpEvent() 72 | this.removeMouseUpEvent = null 73 | } 74 | } 75 | 76 | this.captured = false 77 | 78 | if (this.dragging) { 79 | this.dragging = false 80 | this.clientX = 0 81 | this.clientY = 0 82 | this.deltaX = 0 83 | this.deltaY = 0 84 | } 85 | } 86 | 87 | isDragging() { 88 | return this.dragging 89 | } 90 | 91 | onMouseMove = (e) => { 92 | const x = e.clientX 93 | const y = e.clientY 94 | 95 | this.deltaX += x - this.clientX 96 | this.deltaY += y - this.clientY 97 | 98 | if (this.animationFrameID == null) { 99 | this.animationFrameID = requestAnimationFrame( 100 | this.triggerOnMouseMoveCallback, 101 | ) 102 | } 103 | 104 | this.clientX = x 105 | this.clientY = y 106 | 107 | e.preventDefault() 108 | } 109 | 110 | onMouseUp = () => { 111 | if (this.animationFrameID) { 112 | cancelAnimationFrame(this.animationFrameID) 113 | this.triggerOnMouseMoveCallback() 114 | } 115 | 116 | this.triggerOnMouseMoveEndCallback(false) 117 | } 118 | 119 | triggerOnMouseMoveCallback = () => { 120 | this.animationFrameID = null 121 | this.onMouseMoveCallback(this.deltaX, this.deltaY, { 122 | clientX: this.clientX, 123 | clientY: this.clientY, 124 | }) 125 | this.deltaX = 0 126 | this.deltaY = 0 127 | } 128 | 129 | triggerOnMouseMoveEndCallback = (cancel = false) => { 130 | this.onMouseMoveEndCallback(cancel) 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /docs/components/button/demo.vue: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /docs/components/scrollbox/xy.vue: -------------------------------------------------------------------------------- 1 | 37 | -------------------------------------------------------------------------------- /docs/.vitepress/utils/activeBar.js: -------------------------------------------------------------------------------- 1 | import { onMounted, onUnmounted, onUpdated } from 'vue' 2 | 3 | export function useActiveSidebarLinks(container, marker) { 4 | const throttleAndDebounce = (fn, delay) => { 5 | let timeout = null; 6 | let called = false 7 | return () => { 8 | if (timeout) { 9 | clearTimeout(timeout) 10 | } 11 | if (!called) { 12 | fn() 13 | called = true 14 | setTimeout(() => { 15 | called = false 16 | }, delay) 17 | } else { 18 | timeout = setTimeout(fn, delay) 19 | } 20 | } 21 | } 22 | const onScroll = throttleAndDebounce(setActiveLink, 150) 23 | function setActiveLink() { 24 | const sidebarLinks = getSidebarLinks() 25 | const anchors = getAnchors(sidebarLinks) 26 | 27 | if ( 28 | anchors.length && 29 | window.scrollY + window.innerHeight === document.body.offsetHeight 30 | ) { 31 | activateLink(anchors[anchors.length - 1].hash) 32 | return 33 | } 34 | for (let i = 0; i < anchors.length; i++) { 35 | const anchor = anchors[i] 36 | const nextAnchor = anchors[i + 1] 37 | const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor) 38 | if (isActive) { 39 | history.replaceState( 40 | null, 41 | document.title, 42 | hash ? hash : ' ' 43 | ) 44 | activateLink(hash) 45 | return 46 | } 47 | } 48 | } 49 | 50 | let prevActiveLink = null 51 | 52 | function activateLink(hash) { 53 | deactiveLink(prevActiveLink) 54 | 55 | const activeLink = (prevActiveLink = 56 | hash == null 57 | ? null 58 | : (container.value.querySelector( 59 | `.toc-item a[href="${decodeURIComponent(hash)}"]` 60 | ))) 61 | if (activeLink) { 62 | activeLink.classList.add('active') 63 | marker.value.style.opacity = '1' 64 | marker.value.style.top = `${activeLink.offsetTop}px` 65 | } else { 66 | marker.value.style.opacity = '0' 67 | marker.value.style.top = '33px' 68 | } 69 | } 70 | 71 | function deactiveLink(link) { 72 | link && link.classList.remove('active') 73 | } 74 | 75 | function getSidebarLinks() { 76 | return Array.from( 77 | container.value.querySelectorAll('.toc-content .toc-link') 78 | ) 79 | } 80 | 81 | function getAnchors(sidebarLinks) { 82 | return ( 83 | Array.from( 84 | document.querySelectorAll('.page .container .content .header-anchor') 85 | ) 86 | ).filter((anchor) => 87 | sidebarLinks.some((sidebarLink) => sidebarLink.hash === anchor.hash) 88 | ) 89 | } 90 | 91 | function getPageOffset() { 92 | return (document.querySelector('.nav-bar')).offsetHeight 93 | } 94 | function getAnchorTop(anchor) { 95 | const pageOffset = getPageOffset() 96 | try { 97 | return anchor.parentElement.offsetTop - pageOffset - 15 98 | } catch (e) { 99 | return 0 100 | } 101 | } 102 | 103 | function isAnchorActive(index, anchor, nextAnchor) { 104 | const scrollTop = window.scrollY 105 | if (index === 0 && scrollTop === 0) { 106 | return [true, null] 107 | } 108 | if (scrollTop < getAnchorTop(anchor)) { 109 | return [false, null] 110 | } 111 | if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor)) { 112 | return [true, decodeURIComponent(anchor.hash)] 113 | } 114 | return [false, null] 115 | } 116 | 117 | onMounted(() => { 118 | window.requestAnimationFrame(setActiveLink) 119 | window.addEventListener('scroll', onScroll) 120 | }) 121 | 122 | onUpdated(() => { 123 | activateLink(location.hash) 124 | }) 125 | 126 | onUnmounted(() => { 127 | window.removeEventListener('scroll', onScroll) 128 | }) 129 | } 130 | -------------------------------------------------------------------------------- /components/theme-chalk/x6-color-picker.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $color-picker-prefix-cls: '#{$x6-prefix}-color-picker'; 4 | 5 | .#{$color-picker-prefix-cls} { 6 | position: relative; 7 | padding: 3px; 8 | border: 1px solid #e6e6e6; 9 | border-radius: 4px; 10 | display: inline-block; 11 | width: 100%; 12 | &-block { 13 | width: 100%; 14 | height: 18px; 15 | border-radius: 2px; 16 | } 17 | 18 | &-panel { 19 | position: absolute; 20 | z-index: 2001; 21 | transform-origin: center top; 22 | padding: 6px; 23 | box-sizing: content-box; 24 | background-color: #FFF; 25 | border: 1px solid #EBEEF5; 26 | border-radius: 4px; 27 | box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%); 28 | } 29 | 30 | &-panel-left { 31 | left: 0; 32 | } 33 | &-panel-right { 34 | right: 0; 35 | } 36 | 37 | &-canvas { 38 | position: relative; 39 | } 40 | 41 | &-canvas canvas { 42 | left: 0; 43 | top: 0; 44 | } 45 | 46 | &-cur { 47 | width: 3px; 48 | height: 3px; 49 | outline: 2px solid #fff; 50 | margin-left: -1px; 51 | margin-top: -1px; 52 | position: absolute; 53 | border-radius: 50%; 54 | box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgb(0 0 0 / 30%), 0 0 1px 2px rgb(0 0 0 / 40%); 55 | } 56 | 57 | &-bar,&-alpha{ 58 | background-color: #fff; 59 | position: absolute; 60 | cursor: pointer; 61 | border-radius: 1px; 62 | border: 1px solid #f0f0f0; 63 | box-shadow: 0 0 2px rgb(0 0 0 / 60%); 64 | } 65 | 66 | &-bar { 67 | width: 20px; 68 | height: 3px; 69 | left: 0; 70 | top: 0; 71 | margin-left: -1px; 72 | margin-top: -2px; 73 | } 74 | 75 | &-alpha{ 76 | width: 5px; 77 | height: 20px; 78 | left: 100%; 79 | top: 0; 80 | margin-left: -3px; 81 | margin-top: -1px; 82 | } 83 | 84 | &-alpha-silder { 85 | position: relative; 86 | box-sizing: border-box; 87 | width: 256px; 88 | margin-left: 30px; 89 | height: 18px; 90 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); 91 | } 92 | 93 | &-alpha-silder-bar { 94 | position: relative; 95 | background: linear-gradient(to right, rgba(255, 69, 0, 0) 0%, rgb(255, 69, 0) 100%); 96 | height: 100%; 97 | } 98 | 99 | &-control { 100 | display: flex; 101 | justify-content: space-between; 102 | align-items: center; 103 | margin-top: 5px; 104 | } 105 | 106 | &-input { 107 | background-color: #FFF; 108 | background-image: none; 109 | border-radius: 4px; 110 | border: 1px solid #DCDFE6; 111 | box-sizing: border-box; 112 | color: #606266; 113 | display: inline-block; 114 | outline: 0; 115 | padding: 0 15px; 116 | transition: border-color .2s cubic-bezier(.645, .045, .355, 1); 117 | width: 160px; 118 | font-size: 12px; 119 | height: 28px; 120 | line-height: 28px; 121 | } 122 | 123 | &-input:focus { 124 | border-color: #409EFF; 125 | } 126 | 127 | &-btns { 128 | display: flex; 129 | justify-content: space-between; 130 | align-items: center; 131 | } 132 | 133 | &-btn-clear { 134 | font-size: 12px; 135 | color: #409EFF; 136 | cursor: pointer; 137 | } 138 | 139 | &-btn-confirm { 140 | padding: 7px 15px; 141 | margin-left: 10px; 142 | font-size: 12px; 143 | border-radius: 3px; 144 | display: inline-block; 145 | line-height: 1; 146 | white-space: nowrap; 147 | cursor: pointer; 148 | background: #FFF; 149 | border: 1px solid #DCDFE6; 150 | color: #606266; 151 | text-align: center; 152 | box-sizing: border-box; 153 | outline: 0; 154 | font-weight: 500; 155 | } 156 | 157 | &-predefine { 158 | display: flex; 159 | font-size: 12px; 160 | margin-top: 8px; 161 | width: 280px; 162 | } 163 | 164 | &-predefine__colors { 165 | display: flex; 166 | flex-wrap: wrap; 167 | flex: 1 1 0%; 168 | } 169 | 170 | &-predefine__color-selector:nth-child(10n+1) { 171 | margin-left: 0px; 172 | } 173 | 174 | &-predefine__color-selector { 175 | width: 20px; 176 | height: 20px; 177 | cursor: pointer; 178 | margin: 0px 0px 8px 8px; 179 | border-radius: 4px; 180 | } 181 | 182 | &-predefine__color-selector > div { 183 | display: flex; 184 | height: 100%; 185 | border-radius: 3px; 186 | } 187 | } -------------------------------------------------------------------------------- /docs/.vitepress/components/Demo.vue: -------------------------------------------------------------------------------- 1 | 23 | 109 | 147 | -------------------------------------------------------------------------------- /components/x6-menu/MenuItem.vue: -------------------------------------------------------------------------------- 1 | 16 | 135 | -------------------------------------------------------------------------------- /components/theme-chalk/x6-menu.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | 3 | $menu-prefix-cls: '#{$x6-prefix}-menu'; 4 | 5 | $menu-bg: #fff; 6 | $menu-shadow: 0 2px 10px rgba(0, 0, 0, 0.12); 7 | $menu-item-divider-bg: rgba(150, 150, 150, 0.2); 8 | $menu-item-text-color: #595959; 9 | $menu-item-hover-bg: #f5f5f5; 10 | $menu-item-hover-color: #262626; 11 | $menu-submenu-arrow-color: #262626; 12 | 13 | .#{$menu-prefix-cls} { 14 | $self: &; 15 | position: relative; 16 | display: inline-block; 17 | min-width: 160px; 18 | min-height: 32px; 19 | margin: 0; 20 | padding: 4px 0; 21 | background-color: $menu-bg; 22 | outline: 0; 23 | // box-shadow: $menu-shadow; 24 | 25 | &-item { 26 | position: relative; 27 | } 28 | 29 | &-item-active > &-item-button, 30 | &-item:hover > &-item-button { 31 | color: $menu-item-hover-color; 32 | background: $menu-item-hover-bg; 33 | } 34 | 35 | &-item-divider { 36 | display: block; 37 | width: 100%; 38 | height: 1px; 39 | margin: 4px 0; 40 | background: $menu-item-divider-bg; 41 | pointer-events: none; 42 | } 43 | 44 | &-item-button { 45 | position: relative; 46 | display: flex; 47 | align-content: center; 48 | align-items: center; 49 | justify-content: space-between; 50 | width: 100%; 51 | height: 28px; 52 | padding: 0 12px; 53 | color: $menu-item-text-color; 54 | text-align: left; 55 | background: transparent; 56 | border: none; 57 | outline: none; 58 | box-shadow: none; 59 | cursor: pointer; 60 | } 61 | 62 | &-item-hidden { 63 | display: none; 64 | } 65 | 66 | &-item-disabled > &-item-button, 67 | &-item-disabled:hover > &-item-button { 68 | color: $menu-item-text-color; 69 | background-color: transparent; 70 | cursor: not-allowed; 71 | opacity: 0.4; 72 | } 73 | 74 | &-item-icon { 75 | position: absolute; 76 | bottom: -3px; 77 | left: 0px; 78 | width: 24px; 79 | height: 24px; 80 | font-size: 13px; 81 | } 82 | 83 | &-item-text { 84 | padding-right: 56px; 85 | overflow: hidden; 86 | font-size: 13px; 87 | white-space: nowrap; 88 | text-overflow: ellipsis; 89 | margin-left: 4px; 90 | } 91 | 92 | &-item-hotkey { 93 | font-size: 13px; 94 | opacity: 0.75; 95 | } 96 | 97 | &-submenu-arrow, 98 | &-submenu#{$menu-prefix-cls}-item-disabled:hover 99 | & > .#{$menu-prefix-cls}-item-button 100 | & > .#{$menu-prefix-cls}-submenu-arrow { 101 | position: absolute; 102 | top: 10px; 103 | right: 12px; 104 | width: 0; 105 | height: 0; 106 | border-top: 4px solid rgba(0, 0, 0, 0); 107 | border-bottom: 4px solid rgba(0, 0, 0, 0); 108 | border-left: 5px solid $menu-submenu-arrow-color; 109 | opacity: 0.4; 110 | pointer-events: none; 111 | } 112 | 113 | &-submenu-menu, 114 | &-submenu#{$menu-prefix-cls}-item-disabled:hover > &-submenu-menu { 115 | position: absolute; 116 | top: -5px; 117 | left: 100%; 118 | z-index: 9999; 119 | min-width: 200px; 120 | margin-left: -4px; 121 | padding: 5px 0; 122 | background: $menu-bg; 123 | box-shadow: $menu-shadow; 124 | transform: translateX(-10px); 125 | visibility: hidden; 126 | opacity: 0; 127 | transition: all 0.25s cubic-bezier(0.3, 1.2, 0.2, 1); 128 | } 129 | 130 | &-submenu#{$menu-prefix-cls}-item-active, 131 | &-submenu:hover { 132 | & > #{$menu-prefix-cls}-item-button > .#{$menu-prefix-cls}-submenu-arrow { 133 | opacity: 0.75; 134 | } 135 | } 136 | 137 | &-submenu#{$menu-prefix-cls}-item-active > &-submenu-menu, 138 | &-submenu:hover > &-submenu-menu { 139 | transform: translateX(0); 140 | visibility: visible; 141 | opacity: 1; 142 | } 143 | 144 | &.#{$menu-prefix-cls}-has-icon &-item-button { 145 | padding-left: 30px; 146 | 147 | .#{$menu-prefix-cls}-item-icon { 148 | display: flex; 149 | align-items: center; 150 | justify-content: center; 151 | } 152 | 153 | .#{$menu-prefix-cls}-item-text { 154 | padding-left: 2px; 155 | } 156 | } 157 | 158 | &.#{$menu-prefix-cls}-border { 159 | box-shadow: 0 2px 10px rgb(0 0 0 / 12%); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /docs/components/toolbar/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 工具栏 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | :::tip 13 | 14 | `X6Item`组件使用具名插槽`dropdown`传递`X6Toolbar`组件的`onClick`选项 15 | 16 | ::: 17 | 18 | ## 基础工具栏 19 | 20 | :::demo `X6Item`提供`text`选项和默认插槽显示文本 21 | 22 | toolbar/basic 23 | 24 | ::: 25 | 26 | ## 添加图标 27 | 28 | :::demo `X6Item`提供`icon`选项和`icon`插槽显示文本 29 | 30 | toolbar/icon 31 | 32 | ::: 33 | 34 | ## 添加提示 35 | 36 | :::demo `X6Item`提供`tooltip`选项显示提示 37 | 38 | toolbar/tooltip 39 | 40 | ::: 41 | 42 | ## 添加下箭头 43 | 44 | :::demo `X6Toolbar`提供`dropdownArrow`选项显示下箭头 45 | 46 | toolbar/dropdownArrow 47 | 48 | ::: 49 | 50 | ## 添加事件 51 | 52 | :::demo 53 | 54 | toolbar/event 55 | 56 | ::: 57 | 58 | 59 | ## X6Toolbar 属性 60 | 61 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 62 | |-------------|-----------------------------------|-------------------------------------|---------|---------| 63 | | className | 自定义样式名 | string | - | - | 64 | | size | 工具栏大小 | string | `small、big` | `big` | 65 | | align | 工具对齐方式 | string | `left、right` | `left` | 66 | | hoverEffect | 鼠标 Hover 时是否显示一个圆角背景 | boolean | - | `false` | 67 | | onClick | 点击工具栏的回调函数 | (name, value) => void | - | - | 68 | 69 | ## X6Toolbar 插槽 70 | | 插槽名 | 说明 | 子标签 | 71 | |------------------|--------------------------|-----------------------------------------------| 72 | | - | 工具栏内容 | X6Group | 73 | | extra | 工具栏扩展内容 | - | 74 | 75 | ## X6Group 属性 76 | 77 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 78 | |-----------|------------|----------|--------|--------| 79 | | className | 自定义样式名 | string | - | - | 80 | 81 | ## X6Group 插槽 82 | 83 | | 插槽名 | 说明 | 子标签 | 84 | |------------------|--------------------------|-----------------------------------------------| 85 | | - | 工具栏分组内容 | X6Item | 86 | 87 | ## X6Item 属性 88 | 89 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 90 | |----------------|-----------------------------------------------------------------|-------------------------|--------|--------| 91 | | className | 自定义样式名 | string | - | - | 92 | | name | 工具项名称 | string | - | - | 93 | | icon | 工具项图标 | string | - | - | 94 | | text | 显示的文本 | string | - | - | 95 | | hidden | 是否隐藏 | boolean | - | - | 96 | | disabled | 是否禁用 | boolean | - | - | 97 | | active | 是否被激活 | boolean | - | - | 98 | | tooltip | 工具提示文本 | string | - | - | 99 | | tooltipProps | [X6Tooltip](../tooltip/) 组件的选项 | X6TooltipProps | - | - | 100 | | tooltipAsTitle | 是否将提示文本作为工具项的 `title` 属性 | boolean | - | - | 101 | | dropdownArrow | 是否显示下拉菜单箭头 | boolean | - | - | 102 | | dropdownProps | [X6Dropdown](../dropdown/) 组件的选项 | X6DropdownProps | - | - | 103 | | onClick | 点击工具项的回调函数 | (name) => void | - | - | 104 | 105 | ## X6Item 插槽 106 | 107 | | 插槽名 | 说明 | 子标签 | 108 | |------------------|--------------------------|-----------------------------------------------| 109 | | - | 工具栏项文本内容 | - | 110 | | icon | 工具栏项图标内容 | - | 111 | | dropdown | 工具栏项下拉内容 | - | -------------------------------------------------------------------------------- /docs/.vitepress/dist/assets/components_introduction.md.31828ee2.js: -------------------------------------------------------------------------------- 1 | import{_ as a,o as r,c as l,d as e,b as s,t as i,e as o}from"./app.7f45bc5d.js";const b='{"title":"\u7B80\u4ECB","description":"","frontmatter":{"title":"\u7B80\u4ECB"},"headers":[{"level":2,"title":"\u2728 \u7279\u6027","slug":"\u2728-\u7279\u6027"},{"level":2,"title":"\u{1F349} \u4F7F\u7528\u6587\u6863","slug":"\u{1F349}-\u4F7F\u7528\u6587\u6863"}],"relativePath":"components/introduction.md"}',n={},p={id:"frontmatter-title",tabindex:"-1"},g=e("a",{class:"header-anchor",href:"#frontmatter-title"},"#",-1),h=o('

X6 \u662F AntV \u65D7\u4E0B\u7684\u56FE\u7F16\u8F91\u5F15\u64CE\uFF0C\u63D0\u4F9B\u4E86\u4E00\u7CFB\u5217\u5F00\u7BB1\u5373\u7528\u7684\u4EA4\u4E92\u7EC4\u4EF6\u548C\u7B80\u5355\u6613\u7528\u7684\u8282\u70B9\u5B9A\u5236\u80FD\u529B\uFF0C\u65B9\u4FBF\u6211\u4EEC\u5FEB\u901F\u642D\u5EFA\u6D41\u7A0B\u56FE\u3001DAG \u56FE\u3001ER \u56FE\u7B49\u56FE\u5E94\u7528\u3002

\u5982\u679C\u4F60\u8FD8\u6CA1\u6709\u4F7F\u7528\u8FC7 X6\uFF0C \u5EFA\u8BAE\u901A\u8FC7 \u5FEB\u901F\u4E0A\u624B \u62A2\u5148\u4F53\u9A8C X6 \u7684\u9B45\u529B\u3002

MIT LicenseLanguagePRs Welcome

buildcoverageLanguage grade: JavaScript

NPM PackageNPM DownloadsNPM Dependencies

# \u2728 \u7279\u6027

# \u{1F349} \u4F7F\u7528\u6587\u6863

\u672C\u6587\u7AE0\u63D0\u4F9B\u4E86x6\u9002\u914DVue3\u7684\u7EC4\u4EF6\uFF0C\u8BE6\u7EC6\u5982\u4E0B

',10);function c(t,m,d,f,u,v){return r(),l("div",null,[e("h1",p,[g,s(" "+i(t.$frontmatter.title),1)]),h])}var x=a(n,[["render",c]]);export{b as __pageData,x as default}; 2 | -------------------------------------------------------------------------------- /lib/x6-divider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { value: true }); 4 | 5 | var vue = require('vue'); 6 | 7 | function _slicedToArray(arr, i) { 8 | return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); 9 | } 10 | 11 | function _toConsumableArray(arr) { 12 | return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); 13 | } 14 | 15 | function _arrayWithoutHoles(arr) { 16 | if (Array.isArray(arr)) return _arrayLikeToArray(arr); 17 | } 18 | 19 | function _arrayWithHoles(arr) { 20 | if (Array.isArray(arr)) return arr; 21 | } 22 | 23 | function _iterableToArray(iter) { 24 | if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); 25 | } 26 | 27 | function _iterableToArrayLimit(arr, i) { 28 | var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; 29 | 30 | if (_i == null) return; 31 | var _arr = []; 32 | var _n = true; 33 | var _d = false; 34 | 35 | var _s, _e; 36 | 37 | try { 38 | for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { 39 | _arr.push(_s.value); 40 | 41 | if (i && _arr.length === i) break; 42 | } 43 | } catch (err) { 44 | _d = true; 45 | _e = err; 46 | } finally { 47 | try { 48 | if (!_n && _i["return"] != null) _i["return"](); 49 | } finally { 50 | if (_d) throw _e; 51 | } 52 | } 53 | 54 | return _arr; 55 | } 56 | 57 | function _unsupportedIterableToArray(o, minLen) { 58 | if (!o) return; 59 | if (typeof o === "string") return _arrayLikeToArray(o, minLen); 60 | var n = Object.prototype.toString.call(o).slice(8, -1); 61 | if (n === "Object" && o.constructor) n = o.constructor.name; 62 | if (n === "Map" || n === "Set") return Array.from(o); 63 | if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); 64 | } 65 | 66 | function _arrayLikeToArray(arr, len) { 67 | if (len == null || len > arr.length) len = arr.length; 68 | 69 | for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; 70 | 71 | return arr2; 72 | } 73 | 74 | function _nonIterableSpread() { 75 | throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 76 | } 77 | 78 | function _nonIterableRest() { 79 | throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 80 | } 81 | 82 | /** 83 | * Make a map and return a function for checking if a key 84 | * is in that map. 85 | * IMPORTANT: all calls of this function must be prefixed with 86 | * \/\*#\_\_PURE\_\_\*\/ 87 | * So that rollup can tree-shake them if necessary. 88 | */ 89 | 90 | (process.env.NODE_ENV !== 'production') 91 | ? Object.freeze({}) 92 | : {}; 93 | (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; 94 | 95 | var withInstall = function withInstall(main) { 96 | var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 97 | 98 | main.install = function (app) { 99 | for (var _i = 0, _arr = [main].concat(_toConsumableArray(Object.values(extra))); _i < _arr.length; _i++) { 100 | var comp = _arr[_i]; 101 | app.component(comp.name, comp); 102 | } 103 | }; 104 | 105 | if (extra) { 106 | for (var _i2 = 0, _Object$entries = Object.entries(extra); _i2 < _Object$entries.length; _i2++) { 107 | var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2), 108 | key = _Object$entries$_i[0], 109 | comp = _Object$entries$_i[1]; 110 | 111 | main[key] = comp; 112 | } 113 | } 114 | 115 | return main; 116 | }; 117 | 118 | var script = vue.defineComponent({ 119 | name: 'Divider', 120 | setup() { 121 | let menuContext = vue.inject('menuContext'); 122 | let baseCls = menuContext.baseCls; 123 | let menuDividerClassName = vue.computed(() => { 124 | return `${baseCls}-item 125 | ${baseCls}-item-divider 126 | ` 127 | }); 128 | return { 129 | menuDividerClassName 130 | } 131 | } 132 | }); 133 | 134 | function render(_ctx, _cache, $props, $setup, $data, $options) { 135 | return (vue.openBlock(), vue.createBlock("div", { class: _ctx.menuDividerClassName }, null, 2 /* CLASS */)) 136 | } 137 | 138 | script.render = render; 139 | script.__file = "components/x6-menu/Divider.vue"; 140 | 141 | var X6Divider = withInstall(script); 142 | 143 | exports.X6Divider = X6Divider; 144 | exports["default"] = X6Divider; 145 | //# sourceMappingURL=x6-divider.js.map 146 | -------------------------------------------------------------------------------- /lib/x6-group.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { value: true }); 4 | 5 | var vue = require('vue'); 6 | 7 | function _slicedToArray(arr, i) { 8 | return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); 9 | } 10 | 11 | function _toConsumableArray(arr) { 12 | return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); 13 | } 14 | 15 | function _arrayWithoutHoles(arr) { 16 | if (Array.isArray(arr)) return _arrayLikeToArray(arr); 17 | } 18 | 19 | function _arrayWithHoles(arr) { 20 | if (Array.isArray(arr)) return arr; 21 | } 22 | 23 | function _iterableToArray(iter) { 24 | if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); 25 | } 26 | 27 | function _iterableToArrayLimit(arr, i) { 28 | var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; 29 | 30 | if (_i == null) return; 31 | var _arr = []; 32 | var _n = true; 33 | var _d = false; 34 | 35 | var _s, _e; 36 | 37 | try { 38 | for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { 39 | _arr.push(_s.value); 40 | 41 | if (i && _arr.length === i) break; 42 | } 43 | } catch (err) { 44 | _d = true; 45 | _e = err; 46 | } finally { 47 | try { 48 | if (!_n && _i["return"] != null) _i["return"](); 49 | } finally { 50 | if (_d) throw _e; 51 | } 52 | } 53 | 54 | return _arr; 55 | } 56 | 57 | function _unsupportedIterableToArray(o, minLen) { 58 | if (!o) return; 59 | if (typeof o === "string") return _arrayLikeToArray(o, minLen); 60 | var n = Object.prototype.toString.call(o).slice(8, -1); 61 | if (n === "Object" && o.constructor) n = o.constructor.name; 62 | if (n === "Map" || n === "Set") return Array.from(o); 63 | if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); 64 | } 65 | 66 | function _arrayLikeToArray(arr, len) { 67 | if (len == null || len > arr.length) len = arr.length; 68 | 69 | for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; 70 | 71 | return arr2; 72 | } 73 | 74 | function _nonIterableSpread() { 75 | throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 76 | } 77 | 78 | function _nonIterableRest() { 79 | throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 80 | } 81 | 82 | /** 83 | * Make a map and return a function for checking if a key 84 | * is in that map. 85 | * IMPORTANT: all calls of this function must be prefixed with 86 | * \/\*#\_\_PURE\_\_\*\/ 87 | * So that rollup can tree-shake them if necessary. 88 | */ 89 | 90 | (process.env.NODE_ENV !== 'production') 91 | ? Object.freeze({}) 92 | : {}; 93 | (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; 94 | 95 | var withInstall = function withInstall(main) { 96 | var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 97 | 98 | main.install = function (app) { 99 | for (var _i = 0, _arr = [main].concat(_toConsumableArray(Object.values(extra))); _i < _arr.length; _i++) { 100 | var comp = _arr[_i]; 101 | app.component(comp.name, comp); 102 | } 103 | }; 104 | 105 | if (extra) { 106 | for (var _i2 = 0, _Object$entries = Object.entries(extra); _i2 < _Object$entries.length; _i2++) { 107 | var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2), 108 | key = _Object$entries$_i[0], 109 | comp = _Object$entries$_i[1]; 110 | 111 | main[key] = comp; 112 | } 113 | } 114 | 115 | return main; 116 | }; 117 | 118 | var script = vue.defineComponent({ 119 | name: 'Group', 120 | props: { 121 | className: { 122 | type: String, 123 | default: '' 124 | } 125 | }, 126 | setup(props) { 127 | let { className } = vue.toRefs(props); 128 | let toolbarContext = vue.inject('toolbarContext'); 129 | let groupClassName = vue.computed(() => { 130 | return `${toolbarContext.baseCls}-group ${className.value}` 131 | }); 132 | return { 133 | groupClassName 134 | } 135 | } 136 | }); 137 | 138 | function render(_ctx, _cache, $props, $setup, $data, $options) { 139 | return (vue.openBlock(), vue.createBlock("div", { class: _ctx.groupClassName }, [ 140 | vue.renderSlot(_ctx.$slots, "default") 141 | ], 2 /* CLASS */)) 142 | } 143 | 144 | script.render = render; 145 | script.__file = "components/x6-toolbar/Group.vue"; 146 | 147 | var X6Group = withInstall(script); 148 | 149 | exports.X6Group = X6Group; 150 | exports["default"] = X6Group; 151 | //# sourceMappingURL=x6-group.js.map 152 | -------------------------------------------------------------------------------- /docs/components/menubar/basic.vue: -------------------------------------------------------------------------------- 1 | 96 | -------------------------------------------------------------------------------- /components/x6-toolbar/ItemJsx.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/menu/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 菜单 3 | sidebarDepth: 2 4 | --- 5 | 6 | # {{ $frontmatter.title }} 7 | 8 | [[toc]] 9 | 10 | :::doc-toc 11 | 12 | 菜单组件。一般在 [X6Menubar](../menubar/)、[X6ContextMenu](../contextmenu/)、[X6Dropdown](../dropdown/) 组件中使用。 13 | 14 | ## 基础菜单 15 | 16 | :::demo X6Menu子节点是X6MenuItem。`X6Divider`提供分割线。 17 | 18 | menu/basic 19 | 20 | ::: 21 | 22 | :::tip 23 | 24 | 菜单默认是没有边框的,需要添加`border`属性显示边框。 25 | 26 | ::: 27 | 28 | ## 图标菜单 29 | 30 | :::demo 图标的添加有两种方式,第一种是传`icon`class参数,第二种是传`icon`slot。 31 | 32 | menu/icon 33 | 34 | ::: 35 | 36 | ## 添加事件 37 | 38 | :::demo 按照原有react组件原则,没有使用vue的事件原则。 39 | 40 | menu/event 41 | 42 | ::: 43 | 44 | ## 添加热键 45 | 46 | :::demo `autoHotkey`或则`registerHotkey`都可以开启菜单热键功能。 47 | 48 | menu/hotKey 49 | 50 | ::: 51 | 52 | :::tip 53 | 54 | `registerHotkey`选项更灵活,需要配合`hotkeys-js`使用。 55 | 56 | ::: 57 | 58 | ## 二级子菜单 59 | 60 | :::demo `arrow`选项开启菜单箭头。 61 | 62 | menu/submenu 63 | 64 | ::: 65 | 66 | ## 禁用菜单 67 | 68 | :::demo `disabled`选项禁用菜单。 69 | 70 | menu/disabled 71 | 72 | ::: 73 | 74 | 75 | ## X6Menu 属性 76 | 77 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 78 | |------------------|--------------------------|-----------------------------------------------|---------|---------| 79 | | className | 自定义的样式名 | string | - | - | 80 | | border | 菜单边框 | boolean | - | `false` | 81 | | hasIcon | 是否包含 Icon | boolean | - | `false` | 82 | | onClick | 点击 MenuItem 调用此函数 | (name) => void | - | - | 83 | | autoHotkey | 开启菜单自带热键功能 | boolean | - | `false` | 84 | | registerHotkey | 注册快捷键 | (hotkey: handler) => void | - | - | 85 | | unregisterHotkey | 取消注册快捷键 | (hotkey: handler) => void | - | - | 86 | 87 | 88 | ## X6Menu 插槽 89 | 90 | | 插槽名 | 说明 | 子标签 | 91 | |------------------|--------------------------|-----------------------------------------------| 92 | | — | 自定义默认内容 | X6MenuItem/X6SubMenu/X6Divider | 93 | 94 | 95 | ## X6SubMenu 属性 96 | 97 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 98 | |-----------|----------------------------------------------------|------------|---------|---------| 99 | | className | 自定义的样式名 | string | - | - | 100 | | name | 菜单名称(唯一标识),在 Menu 的 `onClick` 回调用使用| string | - | - | 101 | | icon | 菜单图标 | string | - | - | 102 | | text | 菜单文本 | string | - | - | 103 | | hotkey | 菜单快捷键 | string | - | - | 104 | | active | 是否被激活(显示鼠标 Hover 的背景和子菜单) | boolean | - | `false` | 105 | | hidden | 是否隐藏 | boolean | - | `false` | 106 | | disabled | 是否被禁用 | boolean | - | `false` | 107 | | arrow | 是否显示子菜单箭头 | boolean | - | `false` | 108 | 109 | ## X6SubMenu 插槽 110 | 111 | | 插槽名 | 说明 | 子标签 | 112 | |------------------|--------------------------|-----------------------------------------------| 113 | | — | 菜单文本 | - | 114 | | icon | 菜单图标 | - | 115 | 116 | ## X6MenuItem 属性 117 | 118 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 119 | |-----------|----------------------------------------------------|------------|---------|---------| 120 | | className | 自定义的样式名 | string | - | - | 121 | | name | 菜单名称(唯一标识),在 Menu 的 `onClick` 回调中使用,如果不设置 `name` 属性,`onClick` 将不会被调用。| string | - | - | 122 | | icon | 菜单图标 | string | - | - | 123 | | text | 菜单文本 | string | - | - | 124 | | hotkey | 菜单快捷键 | string | - | - | 125 | | active | 是否被激活(显示鼠标 Hover 的背景) | boolean | - | `false` | 126 | | hidden | 是否隐藏 | boolean | - | `false` | 127 | | disabled | 是否被禁用 | boolean | - | `false` | 128 | | onClick | 点击 MenuItem 调用此函数 | () => void | - | - | 129 | 130 | ## X6MenuItem 插槽 131 | 132 | | 插槽名 | 说明 | 子标签 | 133 | |------------------|--------------------------|-----------------------------------------------| 134 | | — | 菜单文本 | - | 135 | | icon | 菜单图标 | - | 136 | 137 | 138 | ## X6Divider 139 | 140 | 菜单项分割线。 -------------------------------------------------------------------------------- /lib/x6-color-picker.css: -------------------------------------------------------------------------------- 1 | .x6-color-picker { 2 | position: relative; 3 | padding: 3px; 4 | border: 1px solid #e6e6e6; 5 | border-radius: 4px; 6 | display: inline-block; 7 | width: 100%; 8 | } 9 | .x6-color-picker-block { 10 | width: 100%; 11 | height: 18px; 12 | border-radius: 2px; 13 | } 14 | .x6-color-picker-panel { 15 | position: absolute; 16 | z-index: 2001; 17 | -webkit-transform-origin: center top; 18 | transform-origin: center top; 19 | padding: 6px; 20 | -webkit-box-sizing: content-box; 21 | box-sizing: content-box; 22 | background-color: #FFF; 23 | border: 1px solid #EBEEF5; 24 | border-radius: 4px; 25 | -webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); 26 | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); 27 | } 28 | .x6-color-picker-panel-left { 29 | left: 0; 30 | } 31 | .x6-color-picker-panel-right { 32 | right: 0; 33 | } 34 | .x6-color-picker-canvas { 35 | position: relative; 36 | } 37 | .x6-color-picker-canvas canvas { 38 | left: 0; 39 | top: 0; 40 | } 41 | .x6-color-picker-cur { 42 | width: 3px; 43 | height: 3px; 44 | outline: 2px solid #fff; 45 | margin-left: -1px; 46 | margin-top: -1px; 47 | position: absolute; 48 | border-radius: 50%; 49 | -webkit-box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0, 0, 0, 0.3), 0 0 1px 2px rgba(0, 0, 0, 0.4); 50 | box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0, 0, 0, 0.3), 0 0 1px 2px rgba(0, 0, 0, 0.4); 51 | } 52 | .x6-color-picker-bar, .x6-color-picker-alpha { 53 | background-color: #fff; 54 | position: absolute; 55 | cursor: pointer; 56 | border-radius: 1px; 57 | border: 1px solid #f0f0f0; 58 | -webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.6); 59 | box-shadow: 0 0 2px rgba(0, 0, 0, 0.6); 60 | } 61 | .x6-color-picker-bar { 62 | width: 20px; 63 | height: 3px; 64 | left: 0; 65 | top: 0; 66 | margin-left: -1px; 67 | margin-top: -2px; 68 | } 69 | .x6-color-picker-alpha { 70 | width: 5px; 71 | height: 20px; 72 | left: 100%; 73 | top: 0; 74 | margin-left: -3px; 75 | margin-top: -1px; 76 | } 77 | .x6-color-picker-alpha-silder { 78 | position: relative; 79 | -webkit-box-sizing: border-box; 80 | box-sizing: border-box; 81 | width: 256px; 82 | margin-left: 30px; 83 | height: 18px; 84 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); 85 | } 86 | .x6-color-picker-alpha-silder-bar { 87 | position: relative; 88 | background: -webkit-gradient(linear, left top, right top, from(rgba(255, 69, 0, 0)), to(orangered)); 89 | background: linear-gradient(to right, rgba(255, 69, 0, 0) 0%, orangered 100%); 90 | height: 100%; 91 | } 92 | .x6-color-picker-control { 93 | display: -webkit-box; 94 | display: -ms-flexbox; 95 | display: flex; 96 | -webkit-box-pack: justify; 97 | -ms-flex-pack: justify; 98 | justify-content: space-between; 99 | -webkit-box-align: center; 100 | -ms-flex-align: center; 101 | align-items: center; 102 | margin-top: 5px; 103 | } 104 | .x6-color-picker-input { 105 | background-color: #FFF; 106 | background-image: none; 107 | border-radius: 4px; 108 | border: 1px solid #DCDFE6; 109 | -webkit-box-sizing: border-box; 110 | box-sizing: border-box; 111 | color: #606266; 112 | display: inline-block; 113 | outline: 0; 114 | padding: 0 15px; 115 | -webkit-transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); 116 | transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); 117 | width: 160px; 118 | font-size: 12px; 119 | height: 28px; 120 | line-height: 28px; 121 | } 122 | .x6-color-picker-input:focus { 123 | border-color: #409EFF; 124 | } 125 | .x6-color-picker-btns { 126 | display: -webkit-box; 127 | display: -ms-flexbox; 128 | display: flex; 129 | -webkit-box-pack: justify; 130 | -ms-flex-pack: justify; 131 | justify-content: space-between; 132 | -webkit-box-align: center; 133 | -ms-flex-align: center; 134 | align-items: center; 135 | } 136 | .x6-color-picker-btn-clear { 137 | font-size: 12px; 138 | color: #409EFF; 139 | cursor: pointer; 140 | } 141 | .x6-color-picker-btn-confirm { 142 | padding: 7px 15px; 143 | margin-left: 10px; 144 | font-size: 12px; 145 | border-radius: 3px; 146 | display: inline-block; 147 | line-height: 1; 148 | white-space: nowrap; 149 | cursor: pointer; 150 | background: #FFF; 151 | border: 1px solid #DCDFE6; 152 | color: #606266; 153 | text-align: center; 154 | -webkit-box-sizing: border-box; 155 | box-sizing: border-box; 156 | outline: 0; 157 | font-weight: 500; 158 | } 159 | .x6-color-picker-predefine { 160 | display: -webkit-box; 161 | display: -ms-flexbox; 162 | display: flex; 163 | font-size: 12px; 164 | margin-top: 8px; 165 | width: 280px; 166 | } 167 | .x6-color-picker-predefine__colors { 168 | display: -webkit-box; 169 | display: -ms-flexbox; 170 | display: flex; 171 | -ms-flex-wrap: wrap; 172 | flex-wrap: wrap; 173 | -webkit-box-flex: 1; 174 | -ms-flex: 1 1 0%; 175 | flex: 1 1 0%; 176 | } 177 | .x6-color-picker-predefine__color-selector:nth-child(10n+1) { 178 | margin-left: 0px; 179 | } 180 | .x6-color-picker-predefine__color-selector { 181 | width: 20px; 182 | height: 20px; 183 | cursor: pointer; 184 | margin: 0px 0px 8px 8px; 185 | border-radius: 4px; 186 | } 187 | .x6-color-picker-predefine__color-selector > div { 188 | display: -webkit-box; 189 | display: -ms-flexbox; 190 | display: flex; 191 | height: 100%; 192 | border-radius: 3px; 193 | } --------------------------------------------------------------------------------