Compare commits
4 Commits
v2.0.6-bet
...
v2.0.6-bet
Author | SHA1 | Date | |
---|---|---|---|
14ba132592 | |||
f43e0a5417 | |||
25b238fd0b | |||
bf536778ca |
@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
@ -11,17 +12,28 @@ export default class Example extends React.Component {
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
selecting: {
|
||||
// selecting: {
|
||||
// enabled: true,
|
||||
// showNodeSelectionBox: true,
|
||||
// },
|
||||
// clipboard: {
|
||||
// enabled: true,
|
||||
// },
|
||||
// keyboard: {
|
||||
// enabled: true,
|
||||
// global: false,
|
||||
// },
|
||||
})
|
||||
|
||||
graph.use(
|
||||
new Keyboard({
|
||||
enabled: true,
|
||||
showNodeSelectionBox: true,
|
||||
},
|
||||
clipboard: {
|
||||
enabled: true,
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
global: false,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
const keyboard = graph.getPlugin('keyboard') as Keyboard
|
||||
keyboard.bindKey('backspace', () => {
|
||||
console.log('backspace')
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
@ -48,30 +60,30 @@ export default class Example extends React.Component {
|
||||
attrs: { label: { text: 'C' } },
|
||||
})
|
||||
|
||||
graph.bindKey('meta+c', () => {
|
||||
const cells = graph.getSelectedCells()
|
||||
if (cells.length) {
|
||||
graph.copy(cells)
|
||||
}
|
||||
return false
|
||||
})
|
||||
// graph.bindKey('meta+c', () => {
|
||||
// const cells = graph.getSelectedCells()
|
||||
// if (cells.length) {
|
||||
// graph.copy(cells)
|
||||
// }
|
||||
// return false
|
||||
// })
|
||||
|
||||
graph.bindKey('meta+v', () => {
|
||||
if (!graph.isClipboardEmpty()) {
|
||||
const cells = graph.paste({ offset: 32 })
|
||||
graph.resetSelection(cells)
|
||||
}
|
||||
console.log(graph.toJSON())
|
||||
return false
|
||||
})
|
||||
// graph.bindKey('meta+v', () => {
|
||||
// if (!graph.isClipboardEmpty()) {
|
||||
// const cells = graph.paste({ offset: 32 })
|
||||
// graph.resetSelection(cells)
|
||||
// }
|
||||
// console.log(graph.toJSON())
|
||||
// return false
|
||||
// })
|
||||
|
||||
graph.bindKey('backspace', () => {
|
||||
graph.removeCells(graph.getSelectedCells())
|
||||
})
|
||||
// graph.bindKey('backspace', () => {
|
||||
// graph.removeCells(graph.getSelectedCells())
|
||||
// })
|
||||
|
||||
graph.on('selection:changed', ({ selected }) => {
|
||||
console.log(selected)
|
||||
})
|
||||
// graph.on('selection:changed', ({ selected }) => {
|
||||
// console.log(selected)
|
||||
// })
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.0.6-beta.2",
|
||||
"version": "2.0.6-beta.3",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-common",
|
||||
"version": "2.0.6-beta.2",
|
||||
"version": "2.0.6-beta.3",
|
||||
"description": "Basic toolkit for x6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
3
packages/x6-common/src/css-loader/index.ts
Normal file
3
packages/x6-common/src/css-loader/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as CssLoader from './loader'
|
||||
|
||||
export { CssLoader }
|
44
packages/x6-common/src/css-loader/loader.ts
Normal file
44
packages/x6-common/src/css-loader/loader.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Platform } from '../platform'
|
||||
|
||||
interface CssModule {
|
||||
name: string
|
||||
styleElement: HTMLStyleElement | null
|
||||
}
|
||||
|
||||
const cssModules: CssModule[] = []
|
||||
|
||||
export function ensure(name: string, content: string) {
|
||||
const cssModule = cssModules.find((m) => m.name === name)
|
||||
if (cssModule) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!Platform.isApplyingHMR()) {
|
||||
const styleElement = document.createElement('style')
|
||||
styleElement.setAttribute('type', 'text/css')
|
||||
styleElement.textContent = content
|
||||
|
||||
const head = document.querySelector('head') as HTMLHeadElement
|
||||
if (head) {
|
||||
head.insertBefore(styleElement, head.firstChild)
|
||||
}
|
||||
|
||||
cssModules.push({
|
||||
name,
|
||||
styleElement,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function clean(name: string) {
|
||||
const index = cssModules.findIndex((m) => m.name === name)
|
||||
|
||||
if (index > -1) {
|
||||
let styleElement = cssModules[index].styleElement
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement)
|
||||
}
|
||||
styleElement = null
|
||||
cssModules.splice(index, 1)
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ export * from './prefix'
|
||||
export * from './selection'
|
||||
export * from './css'
|
||||
export * from './data'
|
||||
export * from './prop'
|
||||
|
||||
// svg
|
||||
// ---
|
||||
|
45
packages/x6-common/src/dom/prop.ts
Normal file
45
packages/x6-common/src/dom/prop.ts
Normal file
@ -0,0 +1,45 @@
|
||||
const propMap: Record<string, string> = {
|
||||
/* GENERAL */
|
||||
class: 'className',
|
||||
contenteditable: 'contentEditable',
|
||||
/* LABEL */
|
||||
for: 'htmlFor',
|
||||
/* INPUT */
|
||||
readonly: 'readOnly',
|
||||
maxlength: 'maxLength',
|
||||
tabindex: 'tabIndex',
|
||||
/* TABLE */
|
||||
colspan: 'colSpan',
|
||||
rowspan: 'rowSpan',
|
||||
/* IMAGE */
|
||||
usemap: 'useMap',
|
||||
}
|
||||
|
||||
export function prop(elem: Element, props: string): any
|
||||
export function prop(elem: Element, props: string, value: any): void
|
||||
export function prop(elem: Element, props: Record<string, any>): void
|
||||
export function prop(
|
||||
elem: Element,
|
||||
props: string | Record<string, any>,
|
||||
value?: any,
|
||||
) {
|
||||
if (!props) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof props === 'string') {
|
||||
props = propMap[props] || props // eslint-disable-line
|
||||
|
||||
if (arguments.length < 3) {
|
||||
return (elem as any)[props]
|
||||
}
|
||||
|
||||
;(elem as any)[props] = value
|
||||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
for (const key in props) {
|
||||
prop(elem, key, props[key])
|
||||
}
|
||||
}
|
@ -21,4 +21,5 @@ export * from './dictionary'
|
||||
export * from './registry'
|
||||
export * from './modifier'
|
||||
export * from './animation'
|
||||
export * from './css-loader'
|
||||
export * from './types'
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { Dom } from '../dom'
|
||||
|
||||
export type ModifierKey = 'alt' | 'ctrl' | 'meta' | 'shift'
|
||||
|
||||
// eslint-disable-next-line
|
||||
@ -51,7 +53,7 @@ export namespace ModifierKey {
|
||||
}
|
||||
|
||||
export function isMatch(
|
||||
e: JQuery.TriggeredEvent | WheelEvent,
|
||||
e: Dom.EventObject | WheelEvent,
|
||||
modifiers?: string | ModifierKey[] | null,
|
||||
strict?: boolean,
|
||||
) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-next",
|
||||
"version": "2.0.6-beta.2",
|
||||
"version": "2.0.6-beta.3",
|
||||
"description": "JavaScript diagramming library that uses SVG and HTML for rendering.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -65,7 +65,7 @@
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@antv/x6-common": "^2.0.6-beta.2",
|
||||
"@antv/x6-common": "^2.0.6-beta.3",
|
||||
"@antv/x6-geometry": "^2.0.6-beta.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Platform } from '@antv/x6-common'
|
||||
import { CssLoader } from '@antv/x6-common'
|
||||
import { Config } from '../config'
|
||||
import { content } from '../style/raw'
|
||||
import { Base } from './base'
|
||||
@ -6,43 +6,12 @@ import { Base } from './base'
|
||||
export class CSSManager extends Base {
|
||||
protected init() {
|
||||
if (Config.autoInsertCSS) {
|
||||
CSSManager.ensure()
|
||||
CssLoader.ensure('core', content)
|
||||
}
|
||||
}
|
||||
|
||||
@CSSManager.dispose()
|
||||
dispose() {
|
||||
CSSManager.clean()
|
||||
}
|
||||
}
|
||||
|
||||
export namespace CSSManager {
|
||||
let styleElement: HTMLStyleElement | null
|
||||
let counter = 0
|
||||
|
||||
export function ensure() {
|
||||
counter += 1
|
||||
if (counter > 1) return
|
||||
|
||||
if (!Platform.isApplyingHMR()) {
|
||||
styleElement = document.createElement('style')
|
||||
styleElement.setAttribute('type', 'text/css')
|
||||
styleElement.textContent = content
|
||||
|
||||
const head = document.querySelector('head') as HTMLHeadElement
|
||||
if (head) {
|
||||
head.insertBefore(styleElement, head.firstChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function clean() {
|
||||
counter -= 1
|
||||
if (counter > 0) return
|
||||
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement)
|
||||
}
|
||||
styleElement = null
|
||||
CssLoader.clean('core')
|
||||
}
|
||||
}
|
||||
|
@ -1052,6 +1052,18 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
return this
|
||||
}
|
||||
|
||||
getPlugin(pluginName: string) {
|
||||
let result: Graph.Plugin | undefined
|
||||
|
||||
this.installedPlugins.forEach((plugin) => {
|
||||
if (plugin.name === pluginName) {
|
||||
result = plugin
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region dispose
|
||||
@ -1195,6 +1207,7 @@ export namespace Graph {
|
||||
|
||||
export namespace Graph {
|
||||
export type Plugin = {
|
||||
name: string
|
||||
init: (graph: Graph, ...options: any[]) => any
|
||||
dispose: () => void
|
||||
}
|
||||
|
21
packages/x6-plugin-keyboard/LICENSE
Normal file
21
packages/x6-plugin-keyboard/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
5
packages/x6-plugin-keyboard/README.md
Normal file
5
packages/x6-plugin-keyboard/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `x6-plugin-keyboard`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
1
packages/x6-plugin-keyboard/index.ts
Normal file
1
packages/x6-plugin-keyboard/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './src'
|
113
packages/x6-plugin-keyboard/package.json
Normal file
113
packages/x6-plugin-keyboard/package.json
Normal file
@ -0,0 +1,113 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-keyboard",
|
||||
"version": "2.0.6-beta.3",
|
||||
"description": "keyboard plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/x6-plugin-keyboard.js",
|
||||
"jsdelivr": "dist/x6-plugin-keyboard.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"es",
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"plugin",
|
||||
"keyboard",
|
||||
"x6",
|
||||
"antv"
|
||||
],
|
||||
"scripts": {
|
||||
"clean:build": "rimraf dist es lib",
|
||||
"clean:coverage": "rimraf ./test/coverage",
|
||||
"clean": "run-p clean:build clean:coverage",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:dev": "run-p build:cjs build:esm",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
"build:watch:cjs": "yarn build:cjs --w",
|
||||
"build": "run-p build:dev build:umd",
|
||||
"prebuild": "run-s lint clean",
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.ts": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"inherits": [
|
||||
"@antv/x6-package-json/cli.json",
|
||||
"@antv/x6-package-json/eslint.json",
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"mousetrap": "^1.6.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@antv/x6-next": "2.0.6-beta.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.4",
|
||||
"@rollup/plugin-replace": "^3.0.0",
|
||||
"@rollup/plugin-typescript": "^8.2.5",
|
||||
"@types/mousetrap": "^1.6.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.0",
|
||||
"@typescript-eslint/parser": "^4.31.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-jest": "^24.4.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-react": "^7.25.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-unicorn": "^36.0.0",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^11.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.6",
|
||||
"prettier": "^2.4.0",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.56.3",
|
||||
"rollup-plugin-auto-external": "^2.0.0",
|
||||
"rollup-plugin-filesize": "^9.1.1",
|
||||
"rollup-plugin-postcss": "^4.0.1",
|
||||
"rollup-plugin-progress": "^1.1.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.4.3"
|
||||
},
|
||||
"author": {
|
||||
"name": "bubkoo",
|
||||
"email": "bubkoo.wy@gmail.com"
|
||||
},
|
||||
"contributors": [],
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/antvis/x6",
|
||||
"bugs": {
|
||||
"url": "https://github.com/antvis/x6/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-common"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
}
|
17
packages/x6-plugin-keyboard/rollup.config.js
Normal file
17
packages/x6-plugin-keyboard/rollup.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
import config from '../../configs/rollup-config'
|
||||
|
||||
export default config({
|
||||
output: [
|
||||
{
|
||||
name: 'X6PluginKeyboard',
|
||||
format: 'umd',
|
||||
file: 'dist/x6-plugin-keyboard.js',
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/x6-next': 'X6',
|
||||
'@antv/x6-common': 'X6Common',
|
||||
},
|
||||
},
|
||||
],
|
||||
external: ['@antv/x6-next', '@antv/x6-common'],
|
||||
})
|
66
packages/x6-plugin-keyboard/src/index.ts
Normal file
66
packages/x6-plugin-keyboard/src/index.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { Disposable } from '@antv/x6-common'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { KeyboardImpl } from './keyboard'
|
||||
|
||||
export class Keyboard extends Disposable {
|
||||
public name = 'keyboard'
|
||||
private keyboard: KeyboardImpl
|
||||
|
||||
constructor(public readonly options: KeyboardImpl.Options) {
|
||||
super()
|
||||
}
|
||||
|
||||
protected init(graph: Graph) {
|
||||
this.keyboard = new KeyboardImpl(this.options, graph)
|
||||
}
|
||||
|
||||
isKeyboardEnabled() {
|
||||
return !this.keyboard.disabled
|
||||
}
|
||||
|
||||
enableKeyboard() {
|
||||
this.keyboard.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disableKeyboard() {
|
||||
this.keyboard.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleKeyboard(enabled?: boolean) {
|
||||
if (enabled != null) {
|
||||
if (enabled !== this.isKeyboardEnabled()) {
|
||||
if (enabled) {
|
||||
this.enableKeyboard()
|
||||
} else {
|
||||
this.disableKeyboard()
|
||||
}
|
||||
}
|
||||
} else if (this.isKeyboardEnabled()) {
|
||||
this.disableKeyboard()
|
||||
} else {
|
||||
this.enableKeyboard()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
bindKey(
|
||||
keys: string | string[],
|
||||
callback: KeyboardImpl.Handler,
|
||||
action?: KeyboardImpl.Action,
|
||||
) {
|
||||
this.keyboard.on(keys, callback, action)
|
||||
return this
|
||||
}
|
||||
|
||||
unbindKey(keys: string | string[], action?: KeyboardImpl.Action) {
|
||||
this.keyboard.off(keys, action)
|
||||
return this
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.keyboard.dispose()
|
||||
}
|
||||
}
|
187
packages/x6-plugin-keyboard/src/keyboard.ts
Normal file
187
packages/x6-plugin-keyboard/src/keyboard.ts
Normal file
@ -0,0 +1,187 @@
|
||||
import Mousetrap from 'mousetrap'
|
||||
import { Dom, FunctionExt, Disposable, IDisablable } from '@antv/x6-common'
|
||||
import { Graph, EventArgs } from '@antv/x6-next'
|
||||
|
||||
export class KeyboardImpl extends Disposable implements IDisablable {
|
||||
public readonly target: HTMLElement | Document
|
||||
private readonly container: HTMLElement
|
||||
private readonly mousetrap: Mousetrap.MousetrapInstance
|
||||
|
||||
constructor(
|
||||
private readonly options: KeyboardImpl.Options,
|
||||
private readonly graph: Graph,
|
||||
) {
|
||||
super()
|
||||
|
||||
const scroller = this.graph.getPlugin('scroller') as any
|
||||
this.container = scroller ? scroller.container : this.graph.container
|
||||
|
||||
if (options.global) {
|
||||
this.target = document
|
||||
} else {
|
||||
this.target = this.container
|
||||
if (!this.disabled) {
|
||||
// ensure the container focusable
|
||||
this.target.setAttribute('tabindex', '-1')
|
||||
}
|
||||
|
||||
// change to mouseup event,prevent page stalling caused by focus
|
||||
this.graph.on('cell:mouseup', this.focus, this)
|
||||
this.graph.on('blank:mouseup', this.focus, this)
|
||||
}
|
||||
|
||||
this.mousetrap = KeyboardImpl.createMousetrap(this)
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.options.enabled !== true
|
||||
}
|
||||
|
||||
enable() {
|
||||
if (this.disabled) {
|
||||
this.options.enabled = true
|
||||
if (this.target instanceof HTMLElement) {
|
||||
this.target.setAttribute('tabindex', '-1')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (!this.disabled) {
|
||||
this.options.enabled = false
|
||||
if (this.target instanceof HTMLElement) {
|
||||
this.target.removeAttribute('tabindex')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
on(
|
||||
keys: string | string[],
|
||||
callback: KeyboardImpl.Handler,
|
||||
action?: KeyboardImpl.Action,
|
||||
) {
|
||||
this.mousetrap.bind(this.getKeys(keys), callback, action)
|
||||
}
|
||||
|
||||
off(keys: string | string[], action?: KeyboardImpl.Action) {
|
||||
this.mousetrap.unbind(this.getKeys(keys), action)
|
||||
}
|
||||
|
||||
private focus(e: EventArgs['node:mouseup']) {
|
||||
const isInputEvent = this.isInputEvent(e.e)
|
||||
if (isInputEvent) {
|
||||
return
|
||||
}
|
||||
const target = this.target as HTMLElement
|
||||
target.focus({
|
||||
preventScroll: true,
|
||||
})
|
||||
}
|
||||
|
||||
private getKeys(keys: string | string[]) {
|
||||
return (Array.isArray(keys) ? keys : [keys]).map((key) =>
|
||||
this.formatkey(key),
|
||||
)
|
||||
}
|
||||
|
||||
protected formatkey(key: string) {
|
||||
const formated = key
|
||||
.toLowerCase()
|
||||
.replace(/\s/g, '')
|
||||
.replace('delete', 'del')
|
||||
.replace('cmd', 'command')
|
||||
|
||||
const formatFn = this.options.format
|
||||
if (formatFn) {
|
||||
return FunctionExt.call(formatFn, this.graph, formated)
|
||||
}
|
||||
|
||||
return formated
|
||||
}
|
||||
|
||||
protected isGraphEvent(e: KeyboardEvent) {
|
||||
const target = (e.srcElement || e.target) as Element
|
||||
const currentTarget = e.currentTarget as Element
|
||||
if (target) {
|
||||
if (
|
||||
target === this.target ||
|
||||
currentTarget === this.target ||
|
||||
target === document.body
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return Dom.contains(this.container, target)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
isInputEvent(e: KeyboardEvent | JQuery.MouseUpEvent) {
|
||||
const target = e.target as Element
|
||||
const tagName = target?.tagName?.toLowerCase()
|
||||
return ['input', 'textarea'].includes(tagName)
|
||||
}
|
||||
|
||||
isEnabledForEvent(e: KeyboardEvent) {
|
||||
const allowed = !this.disabled && this.isGraphEvent(e)
|
||||
const isInputEvent = this.isInputEvent(e)
|
||||
if (allowed) {
|
||||
const code = e.keyCode || e.which
|
||||
if (isInputEvent && (code === 8 || code === 46)) {
|
||||
return false
|
||||
}
|
||||
if (this.options.guard) {
|
||||
return FunctionExt.call(this.options.guard, this.graph, e)
|
||||
}
|
||||
}
|
||||
return allowed
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.mousetrap.reset()
|
||||
}
|
||||
}
|
||||
|
||||
export namespace KeyboardImpl {
|
||||
export type Action = 'keypress' | 'keydown' | 'keyup'
|
||||
export type Handler = (e: KeyboardEvent) => void
|
||||
|
||||
export interface Options {
|
||||
graph: Graph
|
||||
enabled?: boolean
|
||||
|
||||
/**
|
||||
* Specifies if keyboard event should bind on docuemnt or on container.
|
||||
*
|
||||
* Default is `false` that will bind keyboard event on the container.
|
||||
*/
|
||||
global?: boolean
|
||||
|
||||
format?: (this: Graph, key: string) => string
|
||||
guard?: (this: Graph, e: KeyboardEvent) => boolean
|
||||
}
|
||||
}
|
||||
|
||||
export namespace KeyboardImpl {
|
||||
export function createMousetrap(keyboard: KeyboardImpl) {
|
||||
const mousetrap = new Mousetrap(keyboard.target as Element)
|
||||
const stopCallback = mousetrap.stopCallback
|
||||
mousetrap.stopCallback = (
|
||||
e: KeyboardEvent,
|
||||
elem: HTMLElement,
|
||||
combo: string,
|
||||
) => {
|
||||
if (keyboard.isEnabledForEvent(e)) {
|
||||
if (stopCallback) {
|
||||
return stopCallback.call(mousetrap, e, elem, combo)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return mousetrap
|
||||
}
|
||||
}
|
3
packages/x6-plugin-keyboard/tsconfig.json
Normal file
3
packages/x6-plugin-keyboard/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-scroller",
|
||||
"version": "2.0.6-beta.1",
|
||||
"version": "2.0.6-beta.3",
|
||||
"description": "scroller plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -22,7 +22,7 @@ function compile(source, target) {
|
||||
|
||||
compile(path.join(src, 'index.less'), path.join(es, 'index.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(lib, 'index.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(dist, 'x6.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(dist, 'scroller.css'))
|
||||
|
||||
function toCSSPath(source) {
|
||||
const dir = path.dirname(source)
|
||||
@ -61,7 +61,7 @@ function processLessInDir(dir) {
|
||||
}
|
||||
|
||||
function makeStyleModule() {
|
||||
const source = path.join(dist, 'x6.css')
|
||||
const source = path.join(dist, 'scroller.css')
|
||||
const target = path.join(src, 'style/raw.ts')
|
||||
const content = fs.readFileSync(source, { encoding: 'utf8' })
|
||||
const prev = fs.existsSync(target)
|
||||
|
@ -1,33 +0,0 @@
|
||||
import { Platform } from '@antv/x6-common'
|
||||
import { content } from './style/raw'
|
||||
|
||||
export namespace CSSManager {
|
||||
let styleElement: HTMLStyleElement | null
|
||||
let counter = 0
|
||||
|
||||
export function ensure() {
|
||||
counter += 1
|
||||
if (counter > 1) return
|
||||
|
||||
if (!Platform.isApplyingHMR()) {
|
||||
styleElement = document.createElement('style')
|
||||
styleElement.setAttribute('type', 'text/css')
|
||||
styleElement.textContent = content
|
||||
|
||||
const head = document.querySelector('head') as HTMLHeadElement
|
||||
if (head) {
|
||||
head.insertBefore(styleElement, head.firstChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function clean() {
|
||||
counter -= 1
|
||||
if (counter > 0) return
|
||||
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement)
|
||||
}
|
||||
styleElement = null
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
1433
packages/x6-plugin-scroller/src/scroller.ts
Normal file
1433
packages/x6-plugin-scroller/src/scroller.ts
Normal file
File diff suppressed because it is too large
Load Diff
25
yarn.lock
25
yarn.lock
@ -284,26 +284,6 @@
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
"@antv/x6-common@beta":
|
||||
version "2.0.1-beta.5"
|
||||
resolved "https://registry.npmjs.org/@antv/x6-common/-/x6-common-2.0.1-beta.5.tgz#82d637e1d7494f6830760873c7366a3d5164cbd0"
|
||||
integrity sha512-EmsWptUEW234ZrG4RaOzA+eJAY6wf3S+xgEWw/bqyXN0fOn9LhYJVIWWj+CPOrlLULoZMhnCTvF/pTwcVQOMTQ==
|
||||
dependencies:
|
||||
lodash-es "^4.17.15"
|
||||
|
||||
"@antv/x6-geometry@beta":
|
||||
version "2.0.1-beta.5"
|
||||
resolved "https://registry.npmjs.org/@antv/x6-geometry/-/x6-geometry-2.0.1-beta.5.tgz#66852e1d1b30e88fd654dd0e62925da2d23e1628"
|
||||
integrity sha512-E5ba3j3pKMdRgzCc8pjApc9mmW9JBoVcwNdyqOghIfhHjBd40IhciNvkzwbCclvbmC4nh8qj4mVzLf+1GXVJaA==
|
||||
|
||||
"@antv/x6-next@^2.0.3-beta.0":
|
||||
version "2.0.3-beta.0"
|
||||
resolved "https://registry.npmjs.org/@antv/x6-next/-/x6-next-2.0.3-beta.0.tgz#7b0166df17218dbf0a68f1a11a367962eb39c92d"
|
||||
integrity sha512-FTTyAE6pFL3e/+9qAaHyvwn5rfwooNnNmz//6umDmiitGJl8xBfhAXmw9JLncixcMzvVZQtpCuiS95rENcjSDA==
|
||||
dependencies:
|
||||
"@antv/x6-common" "^2.0.3-beta.0"
|
||||
"@antv/x6-geometry" "^2.0.3-beta.0"
|
||||
|
||||
"@antv/x6-react-components@^1.1.16":
|
||||
version "1.1.16"
|
||||
resolved "https://registry.npmjs.org/@antv/x6-react-components/-/x6-react-components-1.1.16.tgz#51db627d542364d1b0986b2e3f178c166ec114dd"
|
||||
@ -322,11 +302,6 @@
|
||||
resolved "https://registry.npmjs.org/@antv/x6-react-shape/-/x6-react-shape-1.6.0.tgz#62f63a8480bf0f9f3f2abf847625b181f401f926"
|
||||
integrity sha512-sz5sEYUZq9Cm0DpajbPL21N21gowAeMDHfemGuzaVI5Ud07/JS6393spaopcqljVQAY8r7qL+jxxQnWP8hDIBg==
|
||||
|
||||
"@antv/x6-react-shape@^2.0.3-beta.0":
|
||||
version "2.0.3-beta.0"
|
||||
resolved "https://registry.npmjs.org/@antv/x6-react-shape/-/x6-react-shape-2.0.3-beta.0.tgz#9fdfd399bd20896bfbd2f69dda06faef348465e0"
|
||||
integrity sha512-8s2sIUDEEWE73Sr37jdoU+9mQe/f3p+wrwBe97TvOImWiqZSMsj9sULMAnsdO8e++ctjXPu/1fa/P4eJmNhXxg==
|
||||
|
||||
"@ardatan/aggregate-error@0.0.6":
|
||||
version "0.0.6"
|
||||
resolved "https://registry.npmjs.org/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609"
|
||||
|
Reference in New Issue
Block a user