@kwiz/fluentui 1.0.22 → 1.0.24
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/.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 +13 -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 +47 -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 { iDraggedItemType, iDraggableProps } 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> | 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,13 @@
|
|
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
|
+
return _jsx("div", Object.assign({}, (props || {}), { ref: dragDropRef, className: classNames.join(' '), children: props.children }));
|
12
|
+
}
|
13
|
+
//# 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,OAAO,8BAAS,CAAC,KAAK,IAAI,EAAE,CAAC,IAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,YAAG,KAAK,CAAC,QAAQ,IAAO,CAAC;AAC7G,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.24",
|
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,47 @@
|
|
1
|
+
import { isNullOrEmptyString } from "@kwiz/common";
|
2
|
+
import { useDragDropContext } from "./drag-drop-context";
|
3
|
+
import { iDraggedItemType, iDraggableProps } 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>
|
20
|
+
| 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
|
+
return <div {...(props || {})} ref={dragDropRef} className={classNames.join(' ')}>{props.children}</div>;
|
47
|
+
}
|
@@ -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
|
|