@kwiz/fluentui 1.0.22 → 1.0.25
Sign up to get free protection for your applications and to get access to all the features.
- package/.github/workflows/npm-publish.yml +3 -14
- package/dist/controls/dropdown.d.ts +8 -3
- package/dist/controls/dropdown.js +28 -21
- package/dist/controls/dropdown.js.map +1 -1
- package/dist/helpers/drag-drop/drag-drop-container.d.ts +15 -0
- package/dist/helpers/drag-drop/drag-drop-container.js +18 -0
- package/dist/helpers/drag-drop/drag-drop-container.js.map +1 -0
- package/dist/helpers/drag-drop/drag-drop-context.d.ts +30 -0
- package/dist/helpers/drag-drop/drag-drop-context.js +47 -0
- package/dist/helpers/drag-drop/drag-drop-context.js.map +1 -0
- package/dist/helpers/drag-drop/exports.d.ts +4 -0
- package/dist/helpers/drag-drop/exports.js +3 -0
- package/dist/helpers/drag-drop/exports.js.map +1 -0
- package/dist/helpers/drag-drop/use-draggable.d.ts +13 -0
- package/dist/helpers/drag-drop/use-draggable.js +33 -0
- package/dist/helpers/drag-drop/use-draggable.js.map +1 -0
- package/dist/helpers/drag-drop/use-droppable.d.ts +14 -0
- package/dist/helpers/drag-drop/use-droppable.js +28 -0
- package/dist/helpers/drag-drop/use-droppable.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/src/controls/dropdown.tsx +33 -28
- package/src/helpers/drag-drop/drag-drop-container.tsx +55 -0
- package/src/helpers/drag-drop/drag-drop-context.tsx +67 -0
- package/src/helpers/drag-drop/exports.ts +4 -0
- package/src/helpers/drag-drop/readme.md +76 -0
- package/src/helpers/drag-drop/use-draggable.ts +56 -0
- package/src/helpers/drag-drop/use-droppable.ts +48 -0
- package/src/index.ts +1 -0
@@ -9,27 +9,16 @@ on:
|
|
9
9
|
- 'v*.*.*' # run every time we commit with a new version number
|
10
10
|
|
11
11
|
jobs:
|
12
|
-
build:
|
12
|
+
build-publish-npm:
|
13
13
|
runs-on: ubuntu-latest
|
14
14
|
steps:
|
15
15
|
- uses: actions/checkout@v4
|
16
16
|
- uses: actions/setup-node@v4
|
17
17
|
with:
|
18
|
-
node-version:
|
19
|
-
- run: npm ci
|
20
|
-
- run: npm test
|
21
|
-
|
22
|
-
publish-npm:
|
23
|
-
needs: build
|
24
|
-
runs-on: ubuntu-latest
|
25
|
-
steps:
|
26
|
-
- uses: actions/checkout@v4
|
27
|
-
- uses: actions/setup-node@v4
|
28
|
-
with:
|
29
|
-
node-version: 20
|
18
|
+
node-version: 18
|
30
19
|
registry-url: https://registry.npmjs.org/
|
31
20
|
- run: npm ci
|
32
21
|
- run: npm run build
|
33
|
-
- run: npm publish
|
22
|
+
- run: npm run npm-publish
|
34
23
|
env:
|
35
24
|
NODE_AUTH_TOKEN: ${{secrets.KWIZ_NPM_TOKEN}}
|
@@ -25,7 +25,12 @@ interface IProps<dataType, keyType extends string = string> extends ForwardProps
|
|
25
25
|
data?: dataType;
|
26
26
|
}[]) => void;
|
27
27
|
}
|
28
|
-
/**
|
29
|
-
|
30
|
-
|
28
|
+
/** get a DropdownEX typed with forward ref. Usage:
|
29
|
+
* const MyDropdownEX = DropdownEX3<myKeyType, myDataType>();
|
30
|
+
* ...
|
31
|
+
* <MyDropdownEX ... />
|
32
|
+
*/
|
33
|
+
export declare function getDropdownEX<keyType extends string = string, dataType = never>(): React.ForwardRefExoticComponent<IProps<dataType, keyType> & React.RefAttributes<HTMLButtonElement>>;
|
34
|
+
/** to get typed keys use getDropdownEX */
|
35
|
+
export declare const DropdownEX: React.ForwardRefExoticComponent<IProps<never, string> & React.RefAttributes<HTMLButtonElement>>;
|
31
36
|
export {};
|
@@ -3,26 +3,33 @@ import { Dropdown, Option } from '@fluentui/react-components';
|
|
3
3
|
import { filterEmptyEntries, firstOrNull, isNullOrUndefined } from '@kwiz/common';
|
4
4
|
import React from 'react';
|
5
5
|
import { useKWIZFluentContext } from '../helpers/context';
|
6
|
-
/**
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
props.
|
25
|
-
|
6
|
+
/** get a DropdownEX typed with forward ref. Usage:
|
7
|
+
* const MyDropdownEX = DropdownEX3<myKeyType, myDataType>();
|
8
|
+
* ...
|
9
|
+
* <MyDropdownEX ... />
|
10
|
+
*/
|
11
|
+
export function getDropdownEX() {
|
12
|
+
return React.forwardRef((props, ref) => {
|
13
|
+
const ctx = useKWIZFluentContext();
|
14
|
+
const selected = Array.isArray(props.selected) ? props.selected : isNullOrUndefined(props.selected) ? [] : [props.selected];
|
15
|
+
//sometimes control will lose value when re-rendered
|
16
|
+
//use case: public forms when editing other fields after the dropdown was set
|
17
|
+
//re-set the text value manually to fix
|
18
|
+
let text = filterEmptyEntries((Array.isArray(props.selected) ? props.selected : [props.selected]).map(s => {
|
19
|
+
let v = firstOrNull(props.items, i => i.key === s);
|
20
|
+
return v ? v.value : '';
|
21
|
+
})).join(', ');
|
22
|
+
return (_jsx(Dropdown, Object.assign({}, props, { onSelect: undefined, ref: ref, clearable: !props.required && !props.multiselect, appearance: ctx.inputAppearance, mountNode: ctx.mountNode, selectedOptions: selected, value: text, onOptionSelect: (e, data) => {
|
23
|
+
let o = firstOrNull(props.items, i => i.key === data.optionValue);
|
24
|
+
if (props.multiselect) {
|
25
|
+
let current = data.selectedOptions.map(s => firstOrNull(props.items, i => i.key === s));
|
26
|
+
props.onSelect(o, current);
|
27
|
+
}
|
28
|
+
else
|
29
|
+
props.onSelect(o);
|
30
|
+
}, children: props.items.map(i => _jsx(Option, { value: i.key, text: i.value, children: i.option ? i.option : i.value }, i.key)) })));
|
31
|
+
});
|
26
32
|
}
|
27
|
-
|
33
|
+
/** to get typed keys use getDropdownEX */
|
34
|
+
export const DropdownEX = getDropdownEX();
|
28
35
|
//# sourceMappingURL=dropdown.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"dropdown.js","sourceRoot":"","sources":["../../src/controls/dropdown.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAiB,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAmB1D
|
1
|
+
{"version":3,"file":"dropdown.js","sourceRoot":"","sources":["../../src/controls/dropdown.tsx"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { iDraggableProps, iDraggedItemType } from "./use-draggable";
|
2
|
+
import { iDroppableProps } from "./use-droppable";
|
3
|
+
interface one<DragItemType extends iDraggedItemType<string>> {
|
4
|
+
dragInfo: iDraggableProps<DragItemType>;
|
5
|
+
}
|
6
|
+
interface other<DropInfoTypes extends string = never, DropInfoItemTypes extends iDraggedItemType<DropInfoTypes> = never> {
|
7
|
+
dropInfo: iDroppableProps<DropInfoTypes, DropInfoItemTypes>;
|
8
|
+
}
|
9
|
+
type iDragDropProps<DragItemType extends iDraggedItemType<string>, DropInfoTypes extends string = never, DropInfoItemTypes extends iDraggedItemType<DropInfoTypes> = never> = one<DragItemType> & Partial<other<DropInfoTypes, DropInfoItemTypes>> | Partial<one<DragItemType>> & other<DropInfoTypes, DropInfoItemTypes> | (one<DragItemType> & other<DropInfoTypes, DropInfoItemTypes>);
|
10
|
+
type iProps<DragItemType extends iDraggedItemType<string>, DropInfoTypes extends string, DropInfoItemTypes extends iDraggedItemType<DropInfoTypes>> = Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
11
|
+
onDraggingClassName?: string;
|
12
|
+
onDragOverClassName?: string;
|
13
|
+
} & iDragDropProps<DragItemType, DropInfoTypes, DropInfoItemTypes>;
|
14
|
+
export declare function DragDropContainer<DragItemType extends iDraggedItemType<string> = never, DropInfoTypes extends string = never, DropInfoItemTypes extends iDraggedItemType<DropInfoTypes> = never>(props: React.PropsWithChildren<iProps<DragItemType, DropInfoTypes, DropInfoItemTypes>>): import("react/jsx-runtime").JSX.Element;
|
15
|
+
export {};
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { isNullOrEmptyString } from "@kwiz/common";
|
3
|
+
import { useDragDropContext } from "./drag-drop-context";
|
4
|
+
export function DragDropContainer(props) {
|
5
|
+
const { drag, drop, dragDropRef } = useDragDropContext(props);
|
6
|
+
const classNames = isNullOrEmptyString(props.className) ? [] : props.className.split(' ');
|
7
|
+
if (drag.isDragging && props.onDraggingClassName)
|
8
|
+
classNames.push(props.onDraggingClassName);
|
9
|
+
if (drop.isOver && props.onDragOverClassName)
|
10
|
+
classNames.push(props.onDragOverClassName);
|
11
|
+
const propsWithoutExtras = Object.assign({}, props);
|
12
|
+
delete propsWithoutExtras.dragInfo;
|
13
|
+
delete propsWithoutExtras.dropInfo;
|
14
|
+
delete propsWithoutExtras.onDraggingClassName;
|
15
|
+
delete propsWithoutExtras.onDragOverClassName;
|
16
|
+
return _jsx("div", Object.assign({}, propsWithoutExtras, { ref: dragDropRef, className: classNames.join(' '), children: props.children }));
|
17
|
+
}
|
18
|
+
//# sourceMappingURL=drag-drop-container.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"drag-drop-container.js","sourceRoot":"","sources":["../../../src/helpers/drag-drop/drag-drop-container.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAgCzD,MAAM,UAAU,iBAAiB,CAI/B,KAAsF;IAEpF,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAa,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpG,IAAI,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,mBAAmB;QAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC7F,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,mBAAmB;QAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAEzF,MAAM,kBAAkB,qBACjB,KAAK,CACX,CAAC;IACF,OAAO,kBAAkB,CAAC,QAAQ,CAAC;IACnC,OAAO,kBAAkB,CAAC,QAAQ,CAAC;IACnC,OAAO,kBAAkB,CAAC,mBAAmB,CAAC;IAC9C,OAAO,kBAAkB,CAAC,mBAAmB,CAAC;IAE9C,OAAO,8BAAS,kBAAkB,IAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,YAAG,KAAK,CAAC,QAAQ,IAAO,CAAC;AAClH,CAAC"}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { iDraggableProps, iDraggedItemType } from "./use-draggable";
|
3
|
+
import { iDroppableProps } from "./use-droppable";
|
4
|
+
export interface iDragDropContext {
|
5
|
+
isDragging: boolean;
|
6
|
+
setIsDragging: (value: boolean) => void;
|
7
|
+
}
|
8
|
+
export declare const DragDropContext: React.Context<iDragDropContext>;
|
9
|
+
export declare function useDragDropContextInternal(): iDragDropContext;
|
10
|
+
export declare function useDragDropContext<DragItemType extends iDraggedItemType<string> = never, DropInfoType extends iDroppableProps<string, any> = never>(info: {
|
11
|
+
dragInfo?: iDraggableProps<DragItemType>;
|
12
|
+
dropInfo?: DropInfoType;
|
13
|
+
}): {
|
14
|
+
dragDropContext: iDragDropContext;
|
15
|
+
drag: {
|
16
|
+
isDragging: boolean;
|
17
|
+
dragRef: import("react-dnd").ConnectDragSource;
|
18
|
+
};
|
19
|
+
drop: {
|
20
|
+
canDrop: boolean;
|
21
|
+
isOver: boolean;
|
22
|
+
dropRef: import("react-dnd").ConnectDropTarget;
|
23
|
+
};
|
24
|
+
dragDropRef: import("react-dnd").ConnectDragSource;
|
25
|
+
};
|
26
|
+
export declare function useDragDropContextProvider(): iDragDropContext;
|
27
|
+
interface iProps {
|
28
|
+
}
|
29
|
+
export declare const DragDropContextProvider: React.FunctionComponent<React.PropsWithChildren<iProps>>;
|
30
|
+
export {};
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { isNullOrUndefined } from "@kwiz/common";
|
3
|
+
import React, { useContext } from "react";
|
4
|
+
import { DndProvider } from "react-dnd";
|
5
|
+
import { HTML5Backend } from "react-dnd-html5-backend";
|
6
|
+
import { useStateEX } from "../hooks";
|
7
|
+
import { useDraggable } from "./use-draggable";
|
8
|
+
import useDroppable from "./use-droppable";
|
9
|
+
//create context
|
10
|
+
export const DragDropContext = React.createContext(null);
|
11
|
+
//use context from within controls
|
12
|
+
export function useDragDropContextInternal() {
|
13
|
+
const dragDropContext = useContext(DragDropContext);
|
14
|
+
return dragDropContext;
|
15
|
+
}
|
16
|
+
export function useDragDropContext(info) {
|
17
|
+
const dragDropContext = useDragDropContextInternal();
|
18
|
+
const isDraggable = !isNullOrUndefined(info.dragInfo);
|
19
|
+
const isDroppable = !isNullOrUndefined(info.dropInfo);
|
20
|
+
const drag = useDraggable(info === null || info === void 0 ? void 0 : info.dragInfo);
|
21
|
+
const drop = useDroppable(info === null || info === void 0 ? void 0 : info.dropInfo);
|
22
|
+
const acceptDrops = isDroppable && !drag.isDragging && dragDropContext.isDragging;
|
23
|
+
return {
|
24
|
+
dragDropContext,
|
25
|
+
drag,
|
26
|
+
drop,
|
27
|
+
dragDropRef: isDraggable && !isDroppable
|
28
|
+
? drag.dragRef
|
29
|
+
: !isDraggable && isDroppable
|
30
|
+
? drop.dropRef
|
31
|
+
//both drag and drop allowed
|
32
|
+
: acceptDrops ? drop.dropRef : drag.dragRef
|
33
|
+
};
|
34
|
+
}
|
35
|
+
export function useDragDropContextProvider() {
|
36
|
+
const [isDragging, setIsDragging] = useStateEX(false);
|
37
|
+
//build context
|
38
|
+
const ctx = {
|
39
|
+
isDragging, setIsDragging
|
40
|
+
};
|
41
|
+
return ctx;
|
42
|
+
}
|
43
|
+
export const DragDropContextProvider = (props) => {
|
44
|
+
const provider = useDragDropContextProvider();
|
45
|
+
return _jsx(DragDropContext.Provider, { value: provider, children: _jsx(DndProvider, { backend: HTML5Backend, children: props.children }) });
|
46
|
+
};
|
47
|
+
//# sourceMappingURL=drag-drop-context.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"drag-drop-context.js","sourceRoot":"","sources":["../../../src/helpers/drag-drop/drag-drop-context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAqC,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,YAAiC,MAAM,iBAAiB,CAAC;AAMhE,gBAAgB;AAChB,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CAAmB,IAAI,CAAC,CAAC;AAC3E,kCAAkC;AAClC,MAAM,UAAU,0BAA0B;IACtC,MAAM,eAAe,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IACpD,OAAO,eAAe,CAAC;AAC3B,CAAC;AACD,MAAM,UAAU,kBAAkB,CAGhC,IAGD;IACG,MAAM,eAAe,GAAG,0BAA0B,EAAE,CAAC;IACrD,MAAM,WAAW,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,WAAW,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,eAAe,CAAC,UAAU,CAAC;IAElF,OAAO;QACH,eAAe;QACf,IAAI;QACJ,IAAI;QACJ,WAAW,EAAE,WAAW,IAAI,CAAC,WAAW;YACpC,CAAC,CAAC,IAAI,CAAC,OAAO;YACd,CAAC,CAAC,CAAC,WAAW,IAAI,WAAW;gBACzB,CAAC,CAAC,IAAI,CAAC,OAAO;gBACd,4BAA4B;gBAC5B,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO;KACtD,CAAC;AACN,CAAC;AACD,MAAM,UAAU,0BAA0B;IACtC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEtD,eAAe;IACf,MAAM,GAAG,GAAqB;QAC1B,UAAU,EAAE,aAAa;KAC5B,CAAC;IAGF,OAAO,GAAG,CAAC;AACf,CAAC;AAID,MAAM,CAAC,MAAM,uBAAuB,GAA6D,CAAC,KAAK,EAAE,EAAE;IACvG,MAAM,QAAQ,GAAG,0BAA0B,EAAE,CAAC;IAC9C,OAAO,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,QAAQ,YAC5C,KAAC,WAAW,IAAC,OAAO,EAAE,YAAY,YAC7B,KAAK,CAAC,QAAQ,GACL,GACS,CAAC;AAChC,CAAC,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"exports.js","sourceRoot":"","sources":["../../../src/helpers/drag-drop/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { ConnectDragSource } from 'react-dnd';
|
2
|
+
export interface iDraggedItemType<DragType extends string> {
|
3
|
+
type: DragType;
|
4
|
+
}
|
5
|
+
export interface iDraggableProps<ItemType extends iDraggedItemType<string>> {
|
6
|
+
item: ItemType;
|
7
|
+
onBeginDrag?: () => void;
|
8
|
+
onEndDrag?: (dropResult: any) => void;
|
9
|
+
}
|
10
|
+
export declare function useDraggable<ItemType extends iDraggedItemType<string>>(props?: iDraggableProps<ItemType>): {
|
11
|
+
isDragging: boolean;
|
12
|
+
dragRef: ConnectDragSource;
|
13
|
+
};
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { useEffect } from 'react';
|
2
|
+
import { useDrag } from 'react-dnd';
|
3
|
+
import { useDragDropContextInternal } from './drag-drop-context';
|
4
|
+
export function useDraggable(props) {
|
5
|
+
const { item, onBeginDrag, onEndDrag, } = props || {
|
6
|
+
item: {
|
7
|
+
type: "~invalid~"
|
8
|
+
}
|
9
|
+
};
|
10
|
+
const dragDropContext = useDragDropContextInternal();
|
11
|
+
const [{ isDragging }, dragRef] = useDrag(() => ({
|
12
|
+
type: item.type,
|
13
|
+
item,
|
14
|
+
collect: (monitor) => ({
|
15
|
+
isDragging: monitor.isDragging(),
|
16
|
+
}),
|
17
|
+
end: (item, monitor) => {
|
18
|
+
dragDropContext.setIsDragging(false);
|
19
|
+
onEndDrag && onEndDrag(monitor.getDropResult());
|
20
|
+
},
|
21
|
+
}), [item, item.type]);
|
22
|
+
useEffect(() => {
|
23
|
+
if (isDragging) {
|
24
|
+
dragDropContext.setIsDragging(true);
|
25
|
+
onBeginDrag && onBeginDrag();
|
26
|
+
}
|
27
|
+
}, [isDragging, onBeginDrag]);
|
28
|
+
return {
|
29
|
+
isDragging,
|
30
|
+
dragRef,
|
31
|
+
};
|
32
|
+
}
|
33
|
+
//# sourceMappingURL=use-draggable.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"use-draggable.js","sourceRoot":"","sources":["../../../src/helpers/drag-drop/use-draggable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAwC,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAWjE,MAAM,UAAU,YAAY,CAA4C,KAAiC;IAIrG,MAAM,EACF,IAAI,EACJ,WAAW,EACX,SAAS,GACZ,GAAG,KAAK,IAAI;QACT,IAAI,EAAE;YACF,IAAI,EAAE,WAAW;SACpB;KACJ,CAAC;IAEF,MAAM,eAAe,GAAG,0BAA0B,EAAE,CAAC;IAErD,MAAM,CAAC,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,GAAG,OAAO,CACrC,GAAG,EAAE,CAAC,CAAC;QACH,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI;QACJ,OAAO,EAAE,CAAC,OAA0B,EAAE,EAAE,CAAC,CAAC;YACtC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE;SACnC,CAAC;QACF,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YACnB,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACrC,SAAS,IAAI,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QACpD,CAAC;KACJ,CAAC,EACF,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CACpB,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,UAAU,EAAE,CAAC;YACb,eAAe,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACpC,WAAW,IAAI,WAAW,EAAE,CAAC;QACjC,CAAC;IACL,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;IAE7B,OAAO;QACH,UAAU;QACV,OAAO;KACV,CAAC;AACN,CAAC"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { ConnectDropTarget } from 'react-dnd';
|
2
|
+
import { iDraggedItemType } from './use-draggable';
|
3
|
+
export interface iDroppableProps<DropTypes extends string, ItemTypes extends iDraggedItemType<DropTypes>> {
|
4
|
+
acceptTypes: DropTypes[];
|
5
|
+
onItemDrop: (item: ItemTypes) => void;
|
6
|
+
onHover?: (item: ItemTypes) => void;
|
7
|
+
onDrop?: () => void;
|
8
|
+
}
|
9
|
+
declare function useDroppable<DropType extends string, ItemType extends iDraggedItemType<DropType>>(props?: iDroppableProps<DropType, ItemType>): {
|
10
|
+
canDrop: boolean;
|
11
|
+
isOver: boolean;
|
12
|
+
dropRef: ConnectDropTarget;
|
13
|
+
};
|
14
|
+
export default useDroppable;
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { useDrop } from 'react-dnd';
|
2
|
+
function useDroppable(props) {
|
3
|
+
const { acceptTypes, onItemDrop, onHover, onDrop, } = props || {
|
4
|
+
acceptTypes: [],
|
5
|
+
onItemDrop: () => { }
|
6
|
+
};
|
7
|
+
const [{ canDrop, isOver }, dropRef] = useDrop({
|
8
|
+
accept: acceptTypes,
|
9
|
+
drop: (item) => {
|
10
|
+
onItemDrop(item);
|
11
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop();
|
12
|
+
},
|
13
|
+
hover: (item) => {
|
14
|
+
onHover === null || onHover === void 0 ? void 0 : onHover(item);
|
15
|
+
},
|
16
|
+
collect: (monitor) => ({
|
17
|
+
canDrop: monitor.canDrop(),
|
18
|
+
isOver: monitor.isOver(),
|
19
|
+
}),
|
20
|
+
});
|
21
|
+
return {
|
22
|
+
canDrop,
|
23
|
+
isOver,
|
24
|
+
dropRef,
|
25
|
+
};
|
26
|
+
}
|
27
|
+
export default useDroppable;
|
28
|
+
//# sourceMappingURL=use-droppable.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"use-droppable.js","sourceRoot":"","sources":["../../../src/helpers/drag-drop/use-droppable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,OAAO,EAAE,MAAM,WAAW,CAAC;AAU1E,SAAS,YAAY,CAAuE,KAA2C;IAKnI,MAAM,EACF,WAAW,EACX,UAAU,EACV,OAAO,EACP,MAAM,GACT,GAAG,KAAK,IAAI;QACT,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC;KACxB,CAAC;IAEF,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;QAC3C,MAAM,EAAE,WAAW;QACnB,IAAI,EAAE,CAAC,IAAc,EAAE,EAAE;YACrB,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,MAAM,aAAN,MAAM,uBAAN,MAAM,EAAI,CAAC;QACf,CAAC;QACD,KAAK,EAAE,CAAC,IAAc,EAAE,EAAE;YACtB,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,EAAE,CAAC,OAA0B,EAAE,EAAE,CAAC,CAAC;YACtC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;SAC3B,CAAC;KACL,CAAC,CAAC;IAEH,OAAO;QACH,OAAO;QACP,MAAM;QACN,OAAO;KACV,CAAC;AACN,CAAC;AAED,eAAe,YAAY,CAAC"}
|
package/dist/index.d.ts
CHANGED
@@ -21,5 +21,6 @@ export * from './controls/vertical';
|
|
21
21
|
export * from './controls/vertical-content';
|
22
22
|
export { KWIZFluentContext, useKWIZFluentContext } from './helpers/context';
|
23
23
|
export type { iKWIZFluentContext } from './helpers/context';
|
24
|
+
export * from './helpers/drag-drop/exports';
|
24
25
|
export * from './helpers/hooks';
|
25
26
|
export { KnownClassNames } from './styles/styles';
|
package/dist/index.js
CHANGED
@@ -20,6 +20,7 @@ export * from './controls/toolbar';
|
|
20
20
|
export * from './controls/vertical';
|
21
21
|
export * from './controls/vertical-content';
|
22
22
|
export { KWIZFluentContext, useKWIZFluentContext } from './helpers/context';
|
23
|
+
export * from './helpers/drag-drop/exports';
|
23
24
|
export * from './helpers/hooks';
|
24
25
|
export { KnownClassNames } from './styles/styles';
|
25
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@kwiz/fluentui",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.25",
|
4
4
|
"description": "KWIZ common controls for FluentUI",
|
5
5
|
"module": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -59,6 +59,8 @@
|
|
59
59
|
"@kwiz/common": "^1.0.58",
|
60
60
|
"esbuild": "^0.19.12",
|
61
61
|
"get-tsconfig": "^4.7.2",
|
62
|
+
"react-dnd": "^16.0.1",
|
63
|
+
"react-dnd-html5-backend": "^16.0.1",
|
62
64
|
"resolve-pkg-maps": "^1.0.0"
|
63
65
|
},
|
64
66
|
"peerDependencies": {
|
@@ -20,34 +20,39 @@ interface IProps<dataType, keyType extends string = string> extends ForwardProps
|
|
20
20
|
options?: { key: keyType, value: string, data?: dataType }[]) => void;
|
21
21
|
}
|
22
22
|
|
23
|
-
/**
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
/** get a DropdownEX typed with forward ref. Usage:
|
24
|
+
* const MyDropdownEX = DropdownEX3<myKeyType, myDataType>();
|
25
|
+
* ...
|
26
|
+
* <MyDropdownEX ... />
|
27
|
+
*/
|
28
|
+
export function getDropdownEX<keyType extends string = string, dataType = never>() {
|
29
|
+
return React.forwardRef<HTMLButtonElement, (IProps<dataType, keyType>)>((props, ref) => {
|
30
|
+
const ctx = useKWIZFluentContext();
|
31
|
+
const selected: keyType[] = Array.isArray(props.selected) ? props.selected : isNullOrUndefined(props.selected) ? [] : [props.selected];
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
//sometimes control will lose value when re-rendered
|
34
|
+
//use case: public forms when editing other fields after the dropdown was set
|
35
|
+
//re-set the text value manually to fix
|
36
|
+
let text = filterEmptyEntries((Array.isArray(props.selected) ? props.selected : [props.selected]).map(s => {
|
37
|
+
let v = firstOrNull(props.items, i => i.key === s);
|
38
|
+
return v ? v.value : ''
|
39
|
+
})).join(', ');
|
35
40
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
);
|
41
|
+
return (
|
42
|
+
<Dropdown {...{ ...props, onSelect: undefined }} ref={ref} clearable={!props.required && !props.multiselect}
|
43
|
+
appearance={ctx.inputAppearance} mountNode={ctx.mountNode}
|
44
|
+
selectedOptions={selected} value={text} onOptionSelect={(e, data) => {
|
45
|
+
let o = firstOrNull(props.items, i => i.key === data.optionValue);
|
46
|
+
if (props.multiselect) {
|
47
|
+
let current = data.selectedOptions.map(s => firstOrNull(props.items, i => i.key === s));
|
48
|
+
props.onSelect(o, current);
|
49
|
+
}
|
50
|
+
else props.onSelect(o);
|
51
|
+
}}>
|
52
|
+
{props.items.map(i => <Option key={i.key} value={i.key} text={i.value}>{i.option ? i.option : i.value}</Option>)}
|
53
|
+
</Dropdown>
|
54
|
+
);
|
55
|
+
});
|
51
56
|
}
|
52
|
-
|
53
|
-
export const DropdownEX =
|
57
|
+
/** to get typed keys use getDropdownEX */
|
58
|
+
export const DropdownEX = getDropdownEX();
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { isNullOrEmptyString } from "@kwiz/common";
|
2
|
+
import { useDragDropContext } from "./drag-drop-context";
|
3
|
+
import { iDraggableProps, iDraggedItemType } from "./use-draggable";
|
4
|
+
import { iDroppableProps } from "./use-droppable";
|
5
|
+
|
6
|
+
interface one<DragItemType extends iDraggedItemType<string>> {
|
7
|
+
dragInfo: iDraggableProps<DragItemType>;
|
8
|
+
}
|
9
|
+
interface other<
|
10
|
+
DropInfoTypes extends string = never,
|
11
|
+
DropInfoItemTypes extends iDraggedItemType<DropInfoTypes> = never,
|
12
|
+
> {
|
13
|
+
dropInfo: iDroppableProps<DropInfoTypes, DropInfoItemTypes>;
|
14
|
+
}
|
15
|
+
type iDragDropProps<
|
16
|
+
DragItemType extends iDraggedItemType<string>,
|
17
|
+
DropInfoTypes extends string = never,
|
18
|
+
DropInfoItemTypes extends iDraggedItemType<DropInfoTypes> = never,
|
19
|
+
> = one<DragItemType> & Partial<other<DropInfoTypes, DropInfoItemTypes>>
|
20
|
+
| Partial<one<DragItemType>> & other<DropInfoTypes, DropInfoItemTypes>
|
21
|
+
| (one<DragItemType> & other<DropInfoTypes, DropInfoItemTypes>);
|
22
|
+
|
23
|
+
type iProps<DragItemType extends iDraggedItemType<string>, DropInfoTypes extends string, DropInfoItemTypes extends iDraggedItemType<DropInfoTypes>> =
|
24
|
+
//all DIV props, except ref - we need ref.
|
25
|
+
Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">
|
26
|
+
//pass drag class names
|
27
|
+
& {
|
28
|
+
onDraggingClassName?: string;
|
29
|
+
onDragOverClassName?: string;
|
30
|
+
}
|
31
|
+
//drag/drop info
|
32
|
+
& iDragDropProps<DragItemType, DropInfoTypes, DropInfoItemTypes>
|
33
|
+
|
34
|
+
export function DragDropContainer<
|
35
|
+
DragItemType extends iDraggedItemType<string> = never,
|
36
|
+
DropInfoTypes extends string = never,
|
37
|
+
DropInfoItemTypes extends iDraggedItemType<DropInfoTypes> = never
|
38
|
+
>(props: React.PropsWithChildren<iProps<DragItemType, DropInfoTypes, DropInfoItemTypes>>) {
|
39
|
+
|
40
|
+
const { drag, drop, dragDropRef } = useDragDropContext(props);
|
41
|
+
|
42
|
+
const classNames: string[] = isNullOrEmptyString(props.className) ? [] : props.className.split(' ');
|
43
|
+
if (drag.isDragging && props.onDraggingClassName) classNames.push(props.onDraggingClassName);
|
44
|
+
if (drop.isOver && props.onDragOverClassName) classNames.push(props.onDragOverClassName);
|
45
|
+
|
46
|
+
const propsWithoutExtras = {
|
47
|
+
...props
|
48
|
+
};
|
49
|
+
delete propsWithoutExtras.dragInfo;
|
50
|
+
delete propsWithoutExtras.dropInfo;
|
51
|
+
delete propsWithoutExtras.onDraggingClassName;
|
52
|
+
delete propsWithoutExtras.onDragOverClassName;
|
53
|
+
|
54
|
+
return <div {...propsWithoutExtras} ref={dragDropRef} className={classNames.join(' ')}>{props.children}</div>;
|
55
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { isNullOrUndefined } from "@kwiz/common";
|
2
|
+
import React, { useContext } from "react";
|
3
|
+
import { DndProvider } from "react-dnd";
|
4
|
+
import { HTML5Backend } from "react-dnd-html5-backend";
|
5
|
+
import { useStateEX } from "../hooks";
|
6
|
+
import { iDraggableProps, iDraggedItemType, useDraggable } from "./use-draggable";
|
7
|
+
import useDroppable, { iDroppableProps } from "./use-droppable";
|
8
|
+
|
9
|
+
export interface iDragDropContext {
|
10
|
+
isDragging: boolean;
|
11
|
+
setIsDragging: (value: boolean) => void;
|
12
|
+
}
|
13
|
+
//create context
|
14
|
+
export const DragDropContext = React.createContext<iDragDropContext>(null);
|
15
|
+
//use context from within controls
|
16
|
+
export function useDragDropContextInternal() {
|
17
|
+
const dragDropContext = useContext(DragDropContext);
|
18
|
+
return dragDropContext;
|
19
|
+
}
|
20
|
+
export function useDragDropContext<
|
21
|
+
DragItemType extends iDraggedItemType<string> = never,
|
22
|
+
DropInfoType extends iDroppableProps<string, any> = never
|
23
|
+
>(info: {
|
24
|
+
dragInfo?: iDraggableProps<DragItemType>;
|
25
|
+
dropInfo?: DropInfoType;
|
26
|
+
}) {
|
27
|
+
const dragDropContext = useDragDropContextInternal();
|
28
|
+
const isDraggable = !isNullOrUndefined(info.dragInfo);
|
29
|
+
const isDroppable = !isNullOrUndefined(info.dropInfo);
|
30
|
+
const drag = useDraggable(info?.dragInfo);
|
31
|
+
const drop = useDroppable(info?.dropInfo);
|
32
|
+
const acceptDrops = isDroppable && !drag.isDragging && dragDropContext.isDragging;
|
33
|
+
|
34
|
+
return {
|
35
|
+
dragDropContext,
|
36
|
+
drag,
|
37
|
+
drop,
|
38
|
+
dragDropRef: isDraggable && !isDroppable
|
39
|
+
? drag.dragRef
|
40
|
+
: !isDraggable && isDroppable
|
41
|
+
? drop.dropRef
|
42
|
+
//both drag and drop allowed
|
43
|
+
: acceptDrops ? drop.dropRef : drag.dragRef
|
44
|
+
};
|
45
|
+
}
|
46
|
+
export function useDragDropContextProvider(): iDragDropContext {
|
47
|
+
const [isDragging, setIsDragging] = useStateEX(false);
|
48
|
+
|
49
|
+
//build context
|
50
|
+
const ctx: iDragDropContext = {
|
51
|
+
isDragging, setIsDragging
|
52
|
+
};
|
53
|
+
|
54
|
+
|
55
|
+
return ctx;
|
56
|
+
}
|
57
|
+
|
58
|
+
interface iProps {
|
59
|
+
}
|
60
|
+
export const DragDropContextProvider: React.FunctionComponent<React.PropsWithChildren<iProps>> = (props) => {
|
61
|
+
const provider = useDragDropContextProvider();
|
62
|
+
return <DragDropContext.Provider value={provider}>
|
63
|
+
<DndProvider backend={HTML5Backend}>
|
64
|
+
{props.children}
|
65
|
+
</DndProvider>
|
66
|
+
</DragDropContext.Provider>;
|
67
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
Use drag drop with types examples:
|
2
|
+
|
3
|
+
Wrap everything within drag/drop context:
|
4
|
+
```tsx
|
5
|
+
<DragDropContextProvider>
|
6
|
+
...
|
7
|
+
</DragDropContextProvider>
|
8
|
+
```
|
9
|
+
|
10
|
+
Define the types you want to allow drag/drop:
|
11
|
+
```tsx
|
12
|
+
export type dragColumnType = "column";
|
13
|
+
export type dragCellType = "cell";
|
14
|
+
export interface dragColumn extends iDraggedItemType<dragColumnType> {
|
15
|
+
data: iDesignerContextFields
|
16
|
+
}
|
17
|
+
|
18
|
+
export interface dragCell extends iDraggedItemType<dragCellType> {
|
19
|
+
row: number;
|
20
|
+
cell: number;
|
21
|
+
}
|
22
|
+
export interface dropCellOrColumn extends iDroppableProps<dragColumnType | dragCellType, dragColumn | dragCell> {
|
23
|
+
}
|
24
|
+
```
|
25
|
+
|
26
|
+
use within a control:
|
27
|
+
```tsx
|
28
|
+
const { drag, drop, dragDropRef } = useDragDropContext<
|
29
|
+
dragCell, dropCellOrColumn
|
30
|
+
>({
|
31
|
+
dragInfo: {
|
32
|
+
item: {
|
33
|
+
type: "cell",
|
34
|
+
cell: props.index,
|
35
|
+
row: props.rowIndex
|
36
|
+
},
|
37
|
+
},
|
38
|
+
dropInfo: {
|
39
|
+
acceptTypes: ["cell", "column"],
|
40
|
+
onItemDrop: item => {
|
41
|
+
switch (item.type) {
|
42
|
+
case "cell":
|
43
|
+
alert(item.cell);
|
44
|
+
break;
|
45
|
+
case "column":
|
46
|
+
alert(item.data.title);
|
47
|
+
break;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
});
|
52
|
+
|
53
|
+
...
|
54
|
+
|
55
|
+
<Section css={[
|
56
|
+
drop.isOver && classes.hover,
|
57
|
+
drag.isDragging && classes.dragging
|
58
|
+
]}
|
59
|
+
ref={dragDropRef}>
|
60
|
+
...
|
61
|
+
</Section>
|
62
|
+
```
|
63
|
+
|
64
|
+
Use with a wrapper:
|
65
|
+
|
66
|
+
```tsx
|
67
|
+
<DragDropContainer<dragColumn>
|
68
|
+
dragInfo={{
|
69
|
+
item: {
|
70
|
+
type: "column",
|
71
|
+
data: f
|
72
|
+
}
|
73
|
+
}}>
|
74
|
+
<ButtonEX ... />
|
75
|
+
</DragDropContainer>
|
76
|
+
```
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import { useEffect } from 'react';
|
2
|
+
import { ConnectDragSource, DragSourceMonitor, useDrag } from 'react-dnd';
|
3
|
+
import { useDragDropContextInternal } from './drag-drop-context';
|
4
|
+
|
5
|
+
export interface iDraggedItemType<DragType extends string> {
|
6
|
+
type: DragType;
|
7
|
+
}
|
8
|
+
export interface iDraggableProps<ItemType extends iDraggedItemType<string>> {
|
9
|
+
item: ItemType;
|
10
|
+
onBeginDrag?: () => void;
|
11
|
+
onEndDrag?: (dropResult: any) => void;
|
12
|
+
}
|
13
|
+
|
14
|
+
export function useDraggable<ItemType extends iDraggedItemType<string>>(props?: iDraggableProps<ItemType>): {
|
15
|
+
isDragging: boolean;
|
16
|
+
dragRef: ConnectDragSource
|
17
|
+
} {
|
18
|
+
const {
|
19
|
+
item,
|
20
|
+
onBeginDrag,
|
21
|
+
onEndDrag,
|
22
|
+
} = props || {
|
23
|
+
item: {
|
24
|
+
type: "~invalid~"
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
const dragDropContext = useDragDropContextInternal();
|
29
|
+
|
30
|
+
const [{ isDragging }, dragRef] = useDrag(
|
31
|
+
() => ({
|
32
|
+
type: item.type,
|
33
|
+
item,
|
34
|
+
collect: (monitor: DragSourceMonitor) => ({
|
35
|
+
isDragging: monitor.isDragging(),
|
36
|
+
}),
|
37
|
+
end: (item, monitor) => {
|
38
|
+
dragDropContext.setIsDragging(false);
|
39
|
+
onEndDrag && onEndDrag(monitor.getDropResult());
|
40
|
+
},
|
41
|
+
}),
|
42
|
+
[item, item.type]
|
43
|
+
);
|
44
|
+
|
45
|
+
useEffect(() => {
|
46
|
+
if (isDragging) {
|
47
|
+
dragDropContext.setIsDragging(true);
|
48
|
+
onBeginDrag && onBeginDrag();
|
49
|
+
}
|
50
|
+
}, [isDragging, onBeginDrag])
|
51
|
+
|
52
|
+
return {
|
53
|
+
isDragging,
|
54
|
+
dragRef,
|
55
|
+
};
|
56
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { ConnectDropTarget, DropTargetMonitor, useDrop } from 'react-dnd';
|
2
|
+
import { iDraggedItemType } from './use-draggable';
|
3
|
+
|
4
|
+
export interface iDroppableProps<DropTypes extends string, ItemTypes extends iDraggedItemType<DropTypes>> {
|
5
|
+
acceptTypes: DropTypes[];
|
6
|
+
onItemDrop: (item: ItemTypes) => void;
|
7
|
+
onHover?: (item: ItemTypes) => void;
|
8
|
+
onDrop?: () => void;
|
9
|
+
}
|
10
|
+
|
11
|
+
function useDroppable<DropType extends string, ItemType extends iDraggedItemType<DropType>>(props?: iDroppableProps<DropType, ItemType>): {
|
12
|
+
canDrop: boolean;
|
13
|
+
isOver: boolean;
|
14
|
+
dropRef: ConnectDropTarget;
|
15
|
+
} {
|
16
|
+
const {
|
17
|
+
acceptTypes,
|
18
|
+
onItemDrop,
|
19
|
+
onHover,
|
20
|
+
onDrop,
|
21
|
+
} = props || {
|
22
|
+
acceptTypes: [],
|
23
|
+
onItemDrop: () => { }
|
24
|
+
};
|
25
|
+
|
26
|
+
const [{ canDrop, isOver }, dropRef] = useDrop({
|
27
|
+
accept: acceptTypes,
|
28
|
+
drop: (item: ItemType) => {
|
29
|
+
onItemDrop(item);
|
30
|
+
onDrop?.();
|
31
|
+
},
|
32
|
+
hover: (item: ItemType) => {
|
33
|
+
onHover?.(item);
|
34
|
+
},
|
35
|
+
collect: (monitor: DropTargetMonitor) => ({
|
36
|
+
canDrop: monitor.canDrop(),
|
37
|
+
isOver: monitor.isOver(),
|
38
|
+
}),
|
39
|
+
});
|
40
|
+
|
41
|
+
return {
|
42
|
+
canDrop,
|
43
|
+
isOver,
|
44
|
+
dropRef,
|
45
|
+
};
|
46
|
+
}
|
47
|
+
|
48
|
+
export default useDroppable;
|
package/src/index.ts
CHANGED
@@ -21,6 +21,7 @@ export * from './controls/vertical';
|
|
21
21
|
export * from './controls/vertical-content';
|
22
22
|
export { KWIZFluentContext, useKWIZFluentContext } from './helpers/context';
|
23
23
|
export type { iKWIZFluentContext } from './helpers/context';
|
24
|
+
export * from './helpers/drag-drop/exports';
|
24
25
|
export * from './helpers/hooks';
|
25
26
|
export { KnownClassNames } from './styles/styles';
|
26
27
|
|