cx 26.6.0 → 26.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/data/ExposedValueView.js +1 -1
- package/build/data/comparer.d.ts +6 -8
- package/build/data/comparer.d.ts.map +1 -1
- package/build/ui/Cx.d.ts +5 -0
- package/build/ui/Cx.d.ts.map +1 -1
- package/build/ui/Cx.js +34 -3
- package/build/ui/Prop.d.ts +1 -1
- package/build/ui/Prop.d.ts.map +1 -1
- package/build/ui/Restate.d.ts +6 -0
- package/build/ui/Restate.d.ts.map +1 -1
- package/build/ui/Restate.js +2 -1
- package/build/ui/adapter/ArrayAdapter.d.ts +4 -6
- package/build/ui/adapter/ArrayAdapter.d.ts.map +1 -1
- package/build/ui/adapter/GroupAdapter.d.ts +22 -2
- package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
- package/build/ui/adapter/GroupAdapter.js +80 -5
- package/build/widgets/DocumentTitle.d.ts.map +1 -1
- package/build/widgets/DocumentTitle.js +2 -0
- package/build/widgets/drag-drop/DragSource.d.ts +3 -2
- package/build/widgets/drag-drop/DragSource.d.ts.map +1 -1
- package/build/widgets/drag-drop/DropZone.d.ts +4 -4
- package/build/widgets/drag-drop/DropZone.d.ts.map +1 -1
- package/build/widgets/drag-drop/ops.d.ts +13 -2
- package/build/widgets/drag-drop/ops.d.ts.map +1 -1
- package/build/widgets/drag-drop/ops.js +36 -9
- package/build/widgets/form/NumberField.js +1 -0
- package/build/widgets/grid/Grid.d.ts +19 -3
- package/build/widgets/grid/Grid.d.ts.map +1 -1
- package/build/widgets/grid/Grid.js +2 -0
- package/build/widgets/grid/TreeNode.d.ts +2 -0
- package/build/widgets/grid/TreeNode.d.ts.map +1 -1
- package/build/widgets/overlay/captureMouse.d.ts +4 -4
- package/build/widgets/overlay/captureMouse.d.ts.map +1 -1
- package/build/widgets/overlay/captureMouse.js +8 -3
- package/dist/data.js +1 -1
- package/dist/manifest.js +866 -866
- package/dist/ui.js +130 -12
- package/dist/widgets.css +4 -0
- package/dist/widgets.js +43 -10
- package/package.json +1 -1
- package/src/data/ExposedValueView.spec.ts +57 -0
- package/src/data/ExposedValueView.ts +1 -1
- package/src/data/comparer.ts +6 -7
- package/src/ui/Cx.tsx +44 -3
- package/src/ui/DataProxy.ts +55 -55
- package/src/ui/Prop.ts +1 -1
- package/src/ui/Rescope.ts +50 -50
- package/src/ui/Restate.tsx +9 -0
- package/src/ui/adapter/ArrayAdapter.ts +6 -8
- package/src/ui/adapter/GroupAdapter.spec.ts +75 -0
- package/src/ui/adapter/GroupAdapter.ts +103 -10
- package/src/ui/exprHelpers.ts +96 -96
- package/src/widgets/DocumentTitle.ts +2 -0
- package/src/widgets/Sandbox.ts +104 -104
- package/src/widgets/drag-drop/DragSource.tsx +3 -3
- package/src/widgets/drag-drop/DropZone.tsx +5 -5
- package/src/widgets/drag-drop/ops.tsx +54 -12
- package/src/widgets/form/ColorField.scss +112 -112
- package/src/widgets/form/DateTimeField.scss +111 -111
- package/src/widgets/form/LookupField.maps.scss +26 -26
- package/src/widgets/form/MonthField.scss +113 -113
- package/src/widgets/form/NumberField.scss +4 -0
- package/src/widgets/form/NumberField.tsx +1 -0
- package/src/widgets/form/Select.scss +104 -104
- package/src/widgets/form/TextField.scss +66 -66
- package/src/widgets/grid/Grid.tsx +23 -2
- package/src/widgets/grid/TreeNode.tsx +3 -0
- package/src/widgets/nav/MenuItem.tsx +525 -525
- package/src/widgets/overlay/captureMouse.ts +14 -7
package/src/widgets/Sandbox.ts
CHANGED
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
import { Widget } from "../ui/Widget";
|
|
2
|
-
import { PureContainerBase, PureContainerConfig } from "../ui/PureContainer";
|
|
3
|
-
import { Binding, BindingInput } from "../data/Binding";
|
|
4
|
-
import { ExposedValueView, ExposedValueViewConfig } from "../data/ExposedValueView";
|
|
5
|
-
import { RenderingContext } from "../ui/RenderingContext";
|
|
6
|
-
import { Instance } from "../ui/Instance";
|
|
7
|
-
import { StringProp, WritableProp } from "../ui/Prop";
|
|
8
|
-
import { AccessorChain } from "../data/createAccessorModelProxy";
|
|
9
|
-
|
|
10
|
-
export interface SandboxConfig extends PureContainerConfig {
|
|
11
|
-
/** Binding to the object that holds sandbox data. */
|
|
12
|
-
storage: WritableProp<Record<string, any>>;
|
|
13
|
-
|
|
14
|
-
/** Key used to identify the sandbox instance within the storage. */
|
|
15
|
-
key?: StringProp;
|
|
16
|
-
|
|
17
|
-
/** Alias for `key`. */
|
|
18
|
-
accessKey?: StringProp;
|
|
19
|
-
|
|
20
|
-
/** Alias used to expose sandbox data. Default is `$page`. */
|
|
21
|
-
recordName?: string | AccessorChain<any>;
|
|
22
|
-
|
|
23
|
-
/** Alias for `recordName`. */
|
|
24
|
-
recordAlias?: string | AccessorChain<any>;
|
|
25
|
-
|
|
26
|
-
/** Indicate that parent store data should not be mutated. */
|
|
27
|
-
immutable?: boolean;
|
|
28
|
-
|
|
29
|
-
/** Indicate that sandbox store data should not be mutated. */
|
|
30
|
-
sealed?: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface SandboxInstance extends Instance {
|
|
34
|
-
store: ExposedValueView;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class Sandbox extends PureContainerBase<SandboxConfig, SandboxInstance> {
|
|
38
|
-
declare storage: WritableProp<Record<string, any>>;
|
|
39
|
-
declare key?: StringProp;
|
|
40
|
-
declare recordName?: string;
|
|
41
|
-
declare recordAlias?: string;
|
|
42
|
-
declare accessKey?: StringProp;
|
|
43
|
-
declare immutable?: boolean;
|
|
44
|
-
declare sealed?: boolean;
|
|
45
|
-
declare storageBinding: Binding;
|
|
46
|
-
init(): void {
|
|
47
|
-
if (this.recordAlias) this.recordName = this.recordAlias;
|
|
48
|
-
|
|
49
|
-
if (this.accessKey) this.key = this.accessKey;
|
|
50
|
-
|
|
51
|
-
this.storageBinding = Binding.get(this.storage);
|
|
52
|
-
|
|
53
|
-
super.init();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
initInstance(context: RenderingContext, instance: SandboxInstance): void {
|
|
57
|
-
instance.store = new ExposedValueView({
|
|
58
|
-
store: instance.parentStore,
|
|
59
|
-
containerBinding: this.storageBinding,
|
|
60
|
-
key: null,
|
|
61
|
-
recordName: this.recordName,
|
|
62
|
-
immutable: this.immutable,
|
|
63
|
-
});
|
|
64
|
-
super.initInstance(context, instance);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
applyParentStore(instance: SandboxInstance): void {
|
|
68
|
-
instance.store.setStore(instance.parentStore);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
declareData(...args: Record<string, unknown>[]): void {
|
|
72
|
-
super.declareData(
|
|
73
|
-
{
|
|
74
|
-
storage: undefined,
|
|
75
|
-
key: undefined,
|
|
76
|
-
},
|
|
77
|
-
...args,
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
prepareData(context: RenderingContext, instance: SandboxInstance): void {
|
|
82
|
-
var { store, data } = instance;
|
|
83
|
-
if (store.getKey() !== data.key) {
|
|
84
|
-
//when navigating to a page using the same widget tree as the previous page
|
|
85
|
-
//everything needs to be reinstantiated, e.g. user/1 => user/2
|
|
86
|
-
instance.store = new ExposedValueView({
|
|
87
|
-
store: store,
|
|
88
|
-
containerBinding: this.storageBinding,
|
|
89
|
-
key: data.key,
|
|
90
|
-
recordName: this.recordName,
|
|
91
|
-
immutable: this.immutable,
|
|
92
|
-
sealed: this.sealed,
|
|
93
|
-
});
|
|
94
|
-
instance.clearChildrenCache();
|
|
95
|
-
}
|
|
96
|
-
super.prepareData(context, instance);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
Sandbox.prototype.recordName = "$page";
|
|
101
|
-
Sandbox.prototype.immutable = false;
|
|
102
|
-
Sandbox.prototype.sealed = false;
|
|
103
|
-
|
|
104
|
-
Widget.alias("sandbox", Sandbox);
|
|
1
|
+
import { Widget } from "../ui/Widget";
|
|
2
|
+
import { PureContainerBase, PureContainerConfig } from "../ui/PureContainer";
|
|
3
|
+
import { Binding, BindingInput } from "../data/Binding";
|
|
4
|
+
import { ExposedValueView, ExposedValueViewConfig } from "../data/ExposedValueView";
|
|
5
|
+
import { RenderingContext } from "../ui/RenderingContext";
|
|
6
|
+
import { Instance } from "../ui/Instance";
|
|
7
|
+
import { StringProp, WritableProp } from "../ui/Prop";
|
|
8
|
+
import { AccessorChain } from "../data/createAccessorModelProxy";
|
|
9
|
+
|
|
10
|
+
export interface SandboxConfig extends PureContainerConfig {
|
|
11
|
+
/** Binding to the object that holds sandbox data. */
|
|
12
|
+
storage: WritableProp<Record<string, any>>;
|
|
13
|
+
|
|
14
|
+
/** Key used to identify the sandbox instance within the storage. */
|
|
15
|
+
key?: StringProp;
|
|
16
|
+
|
|
17
|
+
/** Alias for `key`. */
|
|
18
|
+
accessKey?: StringProp;
|
|
19
|
+
|
|
20
|
+
/** Alias used to expose sandbox data. Default is `$page`. */
|
|
21
|
+
recordName?: string | AccessorChain<any>;
|
|
22
|
+
|
|
23
|
+
/** Alias for `recordName`. */
|
|
24
|
+
recordAlias?: string | AccessorChain<any>;
|
|
25
|
+
|
|
26
|
+
/** Indicate that parent store data should not be mutated. */
|
|
27
|
+
immutable?: boolean;
|
|
28
|
+
|
|
29
|
+
/** Indicate that sandbox store data should not be mutated. */
|
|
30
|
+
sealed?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SandboxInstance extends Instance {
|
|
34
|
+
store: ExposedValueView;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class Sandbox extends PureContainerBase<SandboxConfig, SandboxInstance> {
|
|
38
|
+
declare storage: WritableProp<Record<string, any>>;
|
|
39
|
+
declare key?: StringProp;
|
|
40
|
+
declare recordName?: string;
|
|
41
|
+
declare recordAlias?: string;
|
|
42
|
+
declare accessKey?: StringProp;
|
|
43
|
+
declare immutable?: boolean;
|
|
44
|
+
declare sealed?: boolean;
|
|
45
|
+
declare storageBinding: Binding;
|
|
46
|
+
init(): void {
|
|
47
|
+
if (this.recordAlias) this.recordName = this.recordAlias;
|
|
48
|
+
|
|
49
|
+
if (this.accessKey) this.key = this.accessKey;
|
|
50
|
+
|
|
51
|
+
this.storageBinding = Binding.get(this.storage);
|
|
52
|
+
|
|
53
|
+
super.init();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
initInstance(context: RenderingContext, instance: SandboxInstance): void {
|
|
57
|
+
instance.store = new ExposedValueView({
|
|
58
|
+
store: instance.parentStore,
|
|
59
|
+
containerBinding: this.storageBinding,
|
|
60
|
+
key: null,
|
|
61
|
+
recordName: this.recordName,
|
|
62
|
+
immutable: this.immutable,
|
|
63
|
+
});
|
|
64
|
+
super.initInstance(context, instance);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
applyParentStore(instance: SandboxInstance): void {
|
|
68
|
+
instance.store.setStore(instance.parentStore);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
declareData(...args: Record<string, unknown>[]): void {
|
|
72
|
+
super.declareData(
|
|
73
|
+
{
|
|
74
|
+
storage: undefined,
|
|
75
|
+
key: undefined,
|
|
76
|
+
},
|
|
77
|
+
...args,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
prepareData(context: RenderingContext, instance: SandboxInstance): void {
|
|
82
|
+
var { store, data } = instance;
|
|
83
|
+
if (store.getKey() !== data.key) {
|
|
84
|
+
//when navigating to a page using the same widget tree as the previous page
|
|
85
|
+
//everything needs to be reinstantiated, e.g. user/1 => user/2
|
|
86
|
+
instance.store = new ExposedValueView({
|
|
87
|
+
store: store,
|
|
88
|
+
containerBinding: this.storageBinding,
|
|
89
|
+
key: data.key,
|
|
90
|
+
recordName: this.recordName,
|
|
91
|
+
immutable: this.immutable,
|
|
92
|
+
sealed: this.sealed,
|
|
93
|
+
});
|
|
94
|
+
instance.clearChildrenCache();
|
|
95
|
+
}
|
|
96
|
+
super.prepareData(context, instance);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Sandbox.prototype.recordName = "$page";
|
|
101
|
+
Sandbox.prototype.immutable = false;
|
|
102
|
+
Sandbox.prototype.sealed = false;
|
|
103
|
+
|
|
104
|
+
Widget.alias("sandbox", Sandbox);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Widget, VDOM } from "../../ui/Widget";
|
|
4
4
|
import { ContainerBase, ContainerConfig, StyledContainerBase, StyledContainerConfig } from "../../ui/Container";
|
|
5
|
-
import { ddMouseDown, ddDetect, ddMouseUp, initiateDragDrop, isDragHandleEvent } from "./ops";
|
|
5
|
+
import { ddMouseDown, ddDetect, ddMouseUp, initiateDragDrop, isDragHandleEvent, DragEndEvent } from "./ops";
|
|
6
6
|
import { preventFocus } from "../../ui/FocusManager";
|
|
7
7
|
import { parseStyle } from "../../util/parseStyle";
|
|
8
8
|
import { Instance } from "../../ui/Instance";
|
|
@@ -30,7 +30,7 @@ export interface DragSourceConfig extends StyledContainerConfig {
|
|
|
30
30
|
|
|
31
31
|
onDragStart?: (e: React.MouseEvent | React.TouchEvent, instance: Instance) => any;
|
|
32
32
|
|
|
33
|
-
onDragEnd?: (e:
|
|
33
|
+
onDragEnd?: (e: DragEndEvent, instance: Instance) => void;
|
|
34
34
|
|
|
35
35
|
id?: StringProp;
|
|
36
36
|
|
|
@@ -64,7 +64,7 @@ export class DragSource extends StyledContainerBase<DragSourceConfig, DragSource
|
|
|
64
64
|
declare cloneStyle: any;
|
|
65
65
|
declare draggedStyle: any;
|
|
66
66
|
declare onDragStart?: (e: React.MouseEvent | React.TouchEvent, instance: DragSourceInstance) => any;
|
|
67
|
-
declare onDragEnd?: (e:
|
|
67
|
+
declare onDragEnd?: (e: DragEndEvent, instance: DragSourceInstance) => void;
|
|
68
68
|
|
|
69
69
|
constructor(config?: DragSourceConfig) {
|
|
70
70
|
super(config);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { Widget, VDOM } from "../../ui/Widget";
|
|
4
4
|
import { ContainerBase, ContainerConfig, StyledContainerBase, StyledContainerConfig } from "../../ui/Container";
|
|
5
5
|
import { parseStyle } from "../../util/parseStyle";
|
|
6
|
-
import { registerDropZone, DragDropContext, DragEvent } from "./ops";
|
|
6
|
+
import { registerDropZone, DragDropContext, DragEvent, DragEndEvent } from "./ops";
|
|
7
7
|
import { findScrollableParent } from "../../util/findScrollableParent";
|
|
8
8
|
import { isNumber } from "../../util/isNumber";
|
|
9
9
|
import { getTopLevelBoundingClientRect } from "../../util/getTopLevelBoundingClientRect";
|
|
@@ -90,8 +90,8 @@ export interface DropZoneConfig extends StyledContainerConfig {
|
|
|
90
90
|
/** A callback method invoked when at the beginning of the drag & drop operation. */
|
|
91
91
|
onDragStart?: string | ((event: DragEvent, instance: Instance) => void);
|
|
92
92
|
|
|
93
|
-
/** A callback method invoked when at the end of the drag & drop operation. */
|
|
94
|
-
onDragEnd?: string | ((event:
|
|
93
|
+
/** A callback method invoked when at the end of the drag & drop operation. `event.cancelled` is `true` when the operation was cancelled (e.g. via Esc) instead of dropped. */
|
|
94
|
+
onDragEnd?: string | ((event: DragEndEvent, instance: Instance) => void);
|
|
95
95
|
|
|
96
96
|
/** Match height of the item being dragged */
|
|
97
97
|
matchHeight?: boolean;
|
|
@@ -126,7 +126,7 @@ export class DropZone extends StyledContainerBase<DropZoneConfig, DropZoneInstan
|
|
|
126
126
|
declare onDragEnter?: string | ((event?: DragEvent, instance?: Instance) => void);
|
|
127
127
|
declare onDragLeave?: string | ((event?: DragEvent, instance?: Instance) => void);
|
|
128
128
|
declare onDragStart?: string | ((event?: DragEvent, instance?: Instance) => void);
|
|
129
|
-
declare onDragEnd?: string | ((event?:
|
|
129
|
+
declare onDragEnd?: string | ((event?: DragEndEvent, instance?: Instance) => void);
|
|
130
130
|
|
|
131
131
|
constructor(config?: DropZoneConfig) {
|
|
132
132
|
super(config);
|
|
@@ -342,7 +342,7 @@ class DropZoneComponent extends VDOM.Component<DropZoneComponentProps, DropZoneC
|
|
|
342
342
|
if (this.state.state == "over" && widget.onDrop) instance.invoke("onDrop", e, instance);
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
onDragEnd(e:
|
|
345
|
+
onDragEnd(e: DragEndEvent) {
|
|
346
346
|
this.setState({
|
|
347
347
|
state: false,
|
|
348
348
|
style: null,
|
|
@@ -21,6 +21,18 @@ export interface DragEvent {
|
|
|
21
21
|
result?: any;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export interface DragEndEvent {
|
|
25
|
+
type: "dragend";
|
|
26
|
+
/** The triggering pointer event, or `null` when the operation was cancelled via the keyboard. */
|
|
27
|
+
event: DragEvent["event"] | null;
|
|
28
|
+
/** Cursor position, or `null` when the operation was cancelled via the keyboard. */
|
|
29
|
+
cursor: CursorPosition | null;
|
|
30
|
+
source: DragEvent["source"];
|
|
31
|
+
/** `true` when the operation was cancelled (e.g. by pressing Esc) instead of dropped. */
|
|
32
|
+
cancelled: boolean;
|
|
33
|
+
result?: any;
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
export interface DragDropOptions {
|
|
25
37
|
sourceEl?: Element | null;
|
|
26
38
|
clone?: any;
|
|
@@ -38,7 +50,7 @@ export interface IDropZone {
|
|
|
38
50
|
onDragStart?: DragEventHandler;
|
|
39
51
|
onDragAway?: DragEventHandler;
|
|
40
52
|
onDragNear?: DragEventHandler;
|
|
41
|
-
onDragEnd?:
|
|
53
|
+
onDragEnd?: (e: DragEndEvent) => void;
|
|
42
54
|
onDragMeasure?: (
|
|
43
55
|
e: DragEvent,
|
|
44
56
|
operation: DragDropOperationContext,
|
|
@@ -62,7 +74,6 @@ import { getTopLevelBoundingClientRect } from "../../util/getTopLevelBoundingCli
|
|
|
62
74
|
import { VDOM } from "../../ui/VDOM";
|
|
63
75
|
import { Container } from "../../ui/Container";
|
|
64
76
|
import { Console } from "../../util";
|
|
65
|
-
import { WidgetConfig } from "../../ui";
|
|
66
77
|
|
|
67
78
|
interface Puppet {
|
|
68
79
|
deltaX: number;
|
|
@@ -70,7 +81,7 @@ interface Puppet {
|
|
|
70
81
|
el: HTMLDivElement;
|
|
71
82
|
clone: any;
|
|
72
83
|
source: any;
|
|
73
|
-
onDragEnd?: (e?:
|
|
84
|
+
onDragEnd?: (e?: DragEndEvent) => void;
|
|
74
85
|
stop?: () => void;
|
|
75
86
|
}
|
|
76
87
|
|
|
@@ -82,6 +93,7 @@ let puppet: Puppet | null = null;
|
|
|
82
93
|
let scrollTimer: number | null = null;
|
|
83
94
|
let vscrollParent: Element | null = null;
|
|
84
95
|
let hscrollParent: Element | null = null;
|
|
96
|
+
let releaseCapture: (() => void) | null = null;
|
|
85
97
|
|
|
86
98
|
export function registerDropZone(dropZone: IDropZone): UnregisterFunction {
|
|
87
99
|
dropZones.push(dropZone);
|
|
@@ -94,7 +106,7 @@ export function registerDropZone(dropZone: IDropZone): UnregisterFunction {
|
|
|
94
106
|
export function initiateDragDrop(
|
|
95
107
|
e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent,
|
|
96
108
|
options: DragDropOptions = {},
|
|
97
|
-
onDragEnd?: (e?:
|
|
109
|
+
onDragEnd?: (e?: DragEndEvent) => void,
|
|
98
110
|
): void {
|
|
99
111
|
if (puppet) {
|
|
100
112
|
//last operation didn't finish properly
|
|
@@ -187,7 +199,16 @@ export function initiateDragDrop(
|
|
|
187
199
|
|
|
188
200
|
notifyDragMove(e, null);
|
|
189
201
|
|
|
190
|
-
captureMouseOrTouch(e, notifyDragMove, notifyDragDrop);
|
|
202
|
+
releaseCapture = captureMouseOrTouch(e, notifyDragMove, notifyDragDrop);
|
|
203
|
+
document.addEventListener("keydown", onDragKeyDown, true);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function onDragKeyDown(e: KeyboardEvent): void {
|
|
207
|
+
if (!puppet || e.key !== "Escape") return;
|
|
208
|
+
//cancel the operation without dropping; there is no pointer event to report
|
|
209
|
+
e.preventDefault();
|
|
210
|
+
e.stopPropagation();
|
|
211
|
+
notifyDragDrop(null, true);
|
|
191
212
|
}
|
|
192
213
|
|
|
193
214
|
function notifyDragMove(e: React.MouseEvent | React.TouchEvent | MouseEvent | TouchEvent, _captureData: any): void {
|
|
@@ -321,29 +342,50 @@ function clearScrollTimer() {
|
|
|
321
342
|
}
|
|
322
343
|
}
|
|
323
344
|
|
|
324
|
-
function notifyDragDrop(
|
|
345
|
+
function notifyDragDrop(
|
|
346
|
+
e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent | null,
|
|
347
|
+
cancelled: boolean = false,
|
|
348
|
+
): void {
|
|
349
|
+
if (!puppet) return;
|
|
350
|
+
|
|
325
351
|
clearScrollTimer();
|
|
352
|
+
document.removeEventListener("keydown", onDragKeyDown, true);
|
|
326
353
|
|
|
327
|
-
|
|
354
|
+
if (puppet.stop) puppet.stop();
|
|
328
355
|
|
|
329
|
-
|
|
356
|
+
//a keyboard cancellation has no pointer event, so the drop and away notifications are skipped
|
|
357
|
+
let dropEvent = !cancelled && e ? getDragEvent(e, "dragdrop") : null;
|
|
330
358
|
|
|
331
|
-
|
|
359
|
+
let result: any;
|
|
360
|
+
if (dropEvent && activeZone && activeZone.onDrop) result = activeZone.onDrop(dropEvent);
|
|
361
|
+
|
|
362
|
+
let endEvent: DragEndEvent = {
|
|
363
|
+
type: "dragend",
|
|
364
|
+
event: e,
|
|
365
|
+
cursor: e ? getCursorPos(e) : null,
|
|
366
|
+
source: puppet.source,
|
|
367
|
+
cancelled,
|
|
368
|
+
result,
|
|
369
|
+
};
|
|
332
370
|
|
|
333
371
|
dropZones.forEach((zone) => {
|
|
334
|
-
if (nearZones != null && zone.onDragAway && nearZones.has(zone)) zone.onDragAway(
|
|
372
|
+
if (dropEvent && nearZones != null && zone.onDragAway && nearZones.has(zone)) zone.onDragAway(dropEvent);
|
|
335
373
|
|
|
336
374
|
if (!dragStartedZones!.has(zone)) return;
|
|
337
375
|
|
|
338
|
-
if (zone.onDragEnd) zone.onDragEnd(
|
|
376
|
+
if (zone.onDragEnd) zone.onDragEnd(endEvent);
|
|
339
377
|
});
|
|
340
378
|
|
|
341
|
-
if (puppet
|
|
379
|
+
if (puppet.onDragEnd) puppet.onDragEnd(endEvent);
|
|
380
|
+
|
|
381
|
+
//tear down the mouse/touch capture when cancelling; on a normal drop the capture ends itself
|
|
382
|
+
if (cancelled && releaseCapture) releaseCapture();
|
|
342
383
|
|
|
343
384
|
nearZones = null;
|
|
344
385
|
activeZone = null;
|
|
345
386
|
puppet = null;
|
|
346
387
|
dragStartedZones = null;
|
|
388
|
+
releaseCapture = null;
|
|
347
389
|
}
|
|
348
390
|
|
|
349
391
|
function getDragEvent(
|
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
@use "sass:math";
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
@use "../variables" as *;
|
|
4
|
-
@use "../maps" as *;
|
|
5
|
-
@use "../../util/call-once.scss" as *;
|
|
6
|
-
@use "../../util/scss/add-rules.scss" as *;
|
|
7
|
-
@use "../../util/scss/calc.scss" as *;
|
|
8
|
-
@use "../../util/scss/clockwise.scss" as *;
|
|
9
|
-
@use "../../util/scss/deep-merge.scss" as *;
|
|
10
|
-
@use "../../util/scss/besm.scss" as *;
|
|
11
|
-
@use "../../util/scss/include.scss" as *;
|
|
12
|
-
@use "./Field.scss" as *;
|
|
13
|
-
@use "./ColorPicker.scss" as *;
|
|
14
|
-
|
|
15
|
-
@mixin cx-colorfield(
|
|
16
|
-
$name: "colorfield",
|
|
17
|
-
$state-style-map: $cx-std-field-state-style-map,
|
|
18
|
-
$placeholder: $cx-input-placeholder,
|
|
19
|
-
$empty-text: $cx-empty-text,
|
|
20
|
-
$clear-state-style-map: $cx-clear-state-style-map,
|
|
21
|
-
$left-icon-state-style-map: $cx-input-left-icon-state-style-map,
|
|
22
|
-
$right-icon-state-style-map: $cx-input-right-icon-state-style-map,
|
|
23
|
-
$width: $cx-default-input-width,
|
|
24
|
-
$icon-size: $cx-default-icon-size,
|
|
25
|
-
$besm: $cx-besm
|
|
26
|
-
) {
|
|
27
|
-
$block: map.get($besm, block);
|
|
28
|
-
$element: map.get($besm, element);
|
|
29
|
-
$state: map.get($besm, state);
|
|
30
|
-
|
|
31
|
-
.#{$block}#{$name} {
|
|
32
|
-
@include cxb-field($besm, $state-style-map, $width: $width, $input: true);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
$padding: cx-get-state-rule($state-style-map, default, "padding");
|
|
36
|
-
|
|
37
|
-
.#{$element}#{$name}-input {
|
|
38
|
-
@include cxe-field-input(
|
|
39
|
-
$besm,
|
|
40
|
-
$state-style-map,
|
|
41
|
-
$placeholder: $placeholder,
|
|
42
|
-
$overrides: (
|
|
43
|
-
default: (
|
|
44
|
-
font-family: $cx-default-colorfield-font-family,
|
|
45
|
-
font-size: 11px,
|
|
46
|
-
padding: cx-top($padding) cx-calc(cx-top($padding), $cx-default-clear-size, $cx-default-clear-spacing)
|
|
47
|
-
cx-bottom($padding)
|
|
48
|
-
cx-calc(cx-top($padding), $cx-default-input-left-tool-size, $cx-default-input-left-tool-spacing),
|
|
49
|
-
)
|
|
50
|
-
)
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.#{$element}#{$name}-clear {
|
|
55
|
-
@include cxe-field-button($besm, $clear-state-style-map);
|
|
56
|
-
|
|
57
|
-
.#{$state}focus > & {
|
|
58
|
-
@include cx-add-state-rules($clear-state-style-map, focus);
|
|
59
|
-
}
|
|
60
|
-
.#{$state}error > & {
|
|
61
|
-
@include cx-add-state-rules($clear-state-style-map, error);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.#{$element}#{$name}-right-icon {
|
|
66
|
-
@include cxe-field-button($besm, $right-icon-state-style-map);
|
|
67
|
-
|
|
68
|
-
.#{$state}focus > & {
|
|
69
|
-
@include cx-add-state-rules($right-icon-state-style-map, focus);
|
|
70
|
-
}
|
|
71
|
-
.#{$state}error > & {
|
|
72
|
-
@include cx-add-state-rules($right-icon-state-style-map, error);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.#{$element}#{$name}-left-icon {
|
|
77
|
-
box-sizing: border-box;
|
|
78
|
-
|
|
79
|
-
@include cx-checker-background();
|
|
80
|
-
|
|
81
|
-
@include cxe-field-button(
|
|
82
|
-
$besm,
|
|
83
|
-
cx-deep-map-merge(
|
|
84
|
-
$left-icon-state-style-map,
|
|
85
|
-
(
|
|
86
|
-
default: (
|
|
87
|
-
opacity: 1,
|
|
88
|
-
cursor: pointer,
|
|
89
|
-
),
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
div {
|
|
95
|
-
width: 100%;
|
|
96
|
-
height: 100%;
|
|
97
|
-
border-radius: inherit;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.#{$element}#{$name}-icon {
|
|
102
|
-
@include cxe-field-button-icon($besm, $icon-size);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.#{$element}#{$name}-empty-text {
|
|
106
|
-
@include cxe-field-empty-text($empty-text);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
@if (cx-should-include("cx/widgets/ColorField")) {
|
|
111
|
-
@include cx-colorfield();
|
|
112
|
-
}
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
@use "../variables" as *;
|
|
4
|
+
@use "../maps" as *;
|
|
5
|
+
@use "../../util/call-once.scss" as *;
|
|
6
|
+
@use "../../util/scss/add-rules.scss" as *;
|
|
7
|
+
@use "../../util/scss/calc.scss" as *;
|
|
8
|
+
@use "../../util/scss/clockwise.scss" as *;
|
|
9
|
+
@use "../../util/scss/deep-merge.scss" as *;
|
|
10
|
+
@use "../../util/scss/besm.scss" as *;
|
|
11
|
+
@use "../../util/scss/include.scss" as *;
|
|
12
|
+
@use "./Field.scss" as *;
|
|
13
|
+
@use "./ColorPicker.scss" as *;
|
|
14
|
+
|
|
15
|
+
@mixin cx-colorfield(
|
|
16
|
+
$name: "colorfield",
|
|
17
|
+
$state-style-map: $cx-std-field-state-style-map,
|
|
18
|
+
$placeholder: $cx-input-placeholder,
|
|
19
|
+
$empty-text: $cx-empty-text,
|
|
20
|
+
$clear-state-style-map: $cx-clear-state-style-map,
|
|
21
|
+
$left-icon-state-style-map: $cx-input-left-icon-state-style-map,
|
|
22
|
+
$right-icon-state-style-map: $cx-input-right-icon-state-style-map,
|
|
23
|
+
$width: $cx-default-input-width,
|
|
24
|
+
$icon-size: $cx-default-icon-size,
|
|
25
|
+
$besm: $cx-besm
|
|
26
|
+
) {
|
|
27
|
+
$block: map.get($besm, block);
|
|
28
|
+
$element: map.get($besm, element);
|
|
29
|
+
$state: map.get($besm, state);
|
|
30
|
+
|
|
31
|
+
.#{$block}#{$name} {
|
|
32
|
+
@include cxb-field($besm, $state-style-map, $width: $width, $input: true);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$padding: cx-get-state-rule($state-style-map, default, "padding");
|
|
36
|
+
|
|
37
|
+
.#{$element}#{$name}-input {
|
|
38
|
+
@include cxe-field-input(
|
|
39
|
+
$besm,
|
|
40
|
+
$state-style-map,
|
|
41
|
+
$placeholder: $placeholder,
|
|
42
|
+
$overrides: (
|
|
43
|
+
default: (
|
|
44
|
+
font-family: $cx-default-colorfield-font-family,
|
|
45
|
+
font-size: 11px,
|
|
46
|
+
padding: cx-top($padding) cx-calc(cx-top($padding), $cx-default-clear-size, $cx-default-clear-spacing)
|
|
47
|
+
cx-bottom($padding)
|
|
48
|
+
cx-calc(cx-top($padding), $cx-default-input-left-tool-size, $cx-default-input-left-tool-spacing),
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.#{$element}#{$name}-clear {
|
|
55
|
+
@include cxe-field-button($besm, $clear-state-style-map);
|
|
56
|
+
|
|
57
|
+
.#{$state}focus > & {
|
|
58
|
+
@include cx-add-state-rules($clear-state-style-map, focus);
|
|
59
|
+
}
|
|
60
|
+
.#{$state}error > & {
|
|
61
|
+
@include cx-add-state-rules($clear-state-style-map, error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.#{$element}#{$name}-right-icon {
|
|
66
|
+
@include cxe-field-button($besm, $right-icon-state-style-map);
|
|
67
|
+
|
|
68
|
+
.#{$state}focus > & {
|
|
69
|
+
@include cx-add-state-rules($right-icon-state-style-map, focus);
|
|
70
|
+
}
|
|
71
|
+
.#{$state}error > & {
|
|
72
|
+
@include cx-add-state-rules($right-icon-state-style-map, error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.#{$element}#{$name}-left-icon {
|
|
77
|
+
box-sizing: border-box;
|
|
78
|
+
|
|
79
|
+
@include cx-checker-background();
|
|
80
|
+
|
|
81
|
+
@include cxe-field-button(
|
|
82
|
+
$besm,
|
|
83
|
+
cx-deep-map-merge(
|
|
84
|
+
$left-icon-state-style-map,
|
|
85
|
+
(
|
|
86
|
+
default: (
|
|
87
|
+
opacity: 1,
|
|
88
|
+
cursor: pointer,
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
div {
|
|
95
|
+
width: 100%;
|
|
96
|
+
height: 100%;
|
|
97
|
+
border-radius: inherit;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.#{$element}#{$name}-icon {
|
|
102
|
+
@include cxe-field-button-icon($besm, $icon-size);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.#{$element}#{$name}-empty-text {
|
|
106
|
+
@include cxe-field-empty-text($empty-text);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@if (cx-should-include("cx/widgets/ColorField")) {
|
|
111
|
+
@include cx-colorfield();
|
|
112
|
+
}
|