@kwiz/fluentui 1.0.56 → 1.0.59
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/.dependency-cruiser.js +399 -0
- package/dist/controls/ColorPickerDialog.js +1 -1
- package/dist/controls/ColorPickerDialog.js.map +1 -1
- package/dist/controls/button.js +1 -1
- package/dist/controls/button.js.map +1 -1
- package/dist/controls/canvas/DrawPad.js +1 -1
- package/dist/controls/canvas/DrawPad.js.map +1 -1
- package/dist/controls/date.js +2 -2
- package/dist/controls/date.js.map +1 -1
- package/dist/controls/diagram-picker.js +2 -2
- package/dist/controls/diagram-picker.js.map +1 -1
- package/dist/controls/dropdown.js +1 -1
- package/dist/controls/dropdown.js.map +1 -1
- package/dist/controls/file-upload.js +16 -10
- package/dist/controls/file-upload.js.map +1 -1
- package/dist/controls/index.d.ts +31 -0
- package/dist/controls/index.js +32 -0
- package/dist/controls/index.js.map +1 -0
- package/dist/controls/input.js +1 -1
- package/dist/controls/input.js.map +1 -1
- package/dist/controls/kwizoverflow.js +1 -1
- package/dist/controls/kwizoverflow.js.map +1 -1
- package/dist/controls/menu.js +2 -2
- package/dist/controls/menu.js.map +1 -1
- package/dist/controls/prompt.js +2 -2
- package/dist/controls/prompt.js.map +1 -1
- package/dist/controls/search.js +1 -1
- package/dist/controls/search.js.map +1 -1
- package/dist/controls/section.js +1 -1
- package/dist/controls/section.js.map +1 -1
- package/dist/controls/vertical-content.js +1 -1
- package/dist/controls/vertical-content.js.map +1 -1
- package/dist/helpers/block-nav.d.ts +11 -0
- package/dist/helpers/block-nav.js +79 -0
- package/dist/helpers/block-nav.js.map +1 -0
- package/dist/helpers/{context.d.ts → context-export.d.ts} +4 -3
- package/dist/helpers/context-export.js +23 -0
- package/dist/helpers/context-export.js.map +1 -0
- package/dist/helpers/context-internal.d.ts +4 -0
- package/dist/helpers/{context.js → context-internal.js} +1 -1
- package/dist/helpers/context-internal.js.map +1 -0
- package/dist/helpers/drag-drop/drag-drop-container.d.ts +1 -2
- package/dist/helpers/drag-drop/drag-drop-container.js.map +1 -1
- package/dist/helpers/drag-drop/drag-drop-context-internal.d.ts +4 -0
- package/dist/helpers/drag-drop/drag-drop-context-internal.js +9 -0
- package/dist/helpers/drag-drop/drag-drop-context-internal.js.map +1 -0
- package/dist/helpers/drag-drop/drag-drop-context.d.ts +1 -9
- package/dist/helpers/drag-drop/drag-drop-context.js +2 -9
- package/dist/helpers/drag-drop/drag-drop-context.js.map +1 -1
- package/dist/helpers/drag-drop/drag-drop.types.d.ts +19 -0
- package/dist/helpers/drag-drop/drag-drop.types.js +2 -0
- package/dist/helpers/drag-drop/drag-drop.types.js.map +1 -0
- package/dist/helpers/drag-drop/{exports.d.ts → index.d.ts} +2 -4
- package/dist/helpers/drag-drop/{exports.js → index.js} +1 -1
- package/dist/helpers/drag-drop/index.js.map +1 -0
- package/dist/helpers/drag-drop/use-draggable.d.ts +1 -8
- package/dist/helpers/drag-drop/use-draggable.js +1 -1
- package/dist/helpers/drag-drop/use-draggable.js.map +1 -1
- package/dist/helpers/drag-drop/use-droppable.d.ts +2 -9
- package/dist/helpers/drag-drop/use-droppable.js +1 -2
- package/dist/helpers/drag-drop/use-droppable.js.map +1 -1
- package/dist/helpers/hooks-events.d.ts +21 -0
- package/dist/helpers/hooks-events.js +146 -0
- package/dist/helpers/hooks-events.js.map +1 -0
- package/dist/helpers/hooks.d.ts +0 -69
- package/dist/helpers/hooks.js +1 -310
- package/dist/helpers/hooks.js.map +1 -1
- package/dist/helpers/index.d.ts +7 -0
- package/dist/helpers/index.js +8 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/use-alerts.d.ts +14 -0
- package/dist/helpers/use-alerts.js +65 -0
- package/dist/helpers/use-alerts.js.map +1 -0
- package/dist/helpers/use-toast.d.ts +18 -0
- package/dist/helpers/use-toast.js +17 -0
- package/dist/helpers/use-toast.js.map +1 -0
- package/dist/index.d.ts +3 -36
- package/dist/index.js +3 -35
- package/dist/index.js.map +1 -1
- package/dist/styles/index.d.ts +1 -0
- package/dist/styles/index.js +2 -0
- package/dist/styles/index.js.map +1 -0
- package/package.json +5 -3
- package/src/controls/ColorPickerDialog.tsx +1 -1
- package/src/controls/button.tsx +1 -1
- package/src/controls/canvas/DrawPad.tsx +1 -1
- package/src/controls/date.tsx +2 -2
- package/src/controls/diagram-picker.tsx +2 -2
- package/src/controls/dropdown.tsx +1 -1
- package/src/controls/file-upload.tsx +18 -11
- package/src/controls/index.ts +31 -0
- package/src/controls/input.tsx +1 -1
- package/src/controls/kwizoverflow.tsx +1 -1
- package/src/controls/menu.tsx +2 -2
- package/src/controls/prompt.tsx +2 -2
- package/src/controls/search.tsx +1 -1
- package/src/controls/section.tsx +1 -1
- package/src/controls/vertical-content.tsx +1 -1
- package/src/helpers/block-nav.tsx +89 -0
- package/src/helpers/context-export.ts +53 -0
- package/src/helpers/context-internal.ts +17 -0
- package/src/helpers/drag-drop/drag-drop-container.tsx +1 -2
- package/src/helpers/drag-drop/drag-drop-context-internal.tsx +10 -0
- package/src/helpers/drag-drop/drag-drop-context.tsx +5 -15
- package/src/helpers/drag-drop/drag-drop.types.ts +21 -0
- package/src/helpers/drag-drop/{exports.ts → index.ts} +2 -4
- package/src/helpers/drag-drop/use-draggable.ts +2 -10
- package/src/helpers/drag-drop/use-droppable.ts +3 -12
- package/src/helpers/hooks-events.ts +153 -0
- package/src/helpers/hooks.tsx +1 -360
- package/src/helpers/index.ts +8 -0
- package/src/helpers/use-alerts.tsx +75 -0
- package/src/helpers/use-toast.tsx +30 -0
- package/src/index.ts +3 -37
- package/src/styles/index.ts +1 -0
- package/dist/helpers/context.js.map +0 -1
- package/dist/helpers/drag-drop/exports.js.map +0 -1
- package/src/helpers/context.ts +0 -40
|
@@ -3,7 +3,7 @@ import { ColorRegular } from "@fluentui/react-icons";
|
|
|
3
3
|
import { isFunction, isNullOrEmptyString, isNumber } from "@kwiz/common";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import ColorPicker, { Color } from 'react-pick-color';
|
|
6
|
-
import { useEffectOnlyOnMount, useStateEX } from "../helpers
|
|
6
|
+
import { useEffectOnlyOnMount, useStateEX } from "../helpers";
|
|
7
7
|
import { ButtonEX } from "./button";
|
|
8
8
|
import { InputEx } from "./input";
|
|
9
9
|
import { Prompter } from "./prompt";
|
package/src/controls/button.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Button, ButtonProps, CompoundButton, compoundButtonClassNames, CompoundButtonProps, makeStyles, mergeClasses, tokens, Tooltip } from '@fluentui/react-components';
|
|
2
2
|
import { capitalizeFirstLetter, isFunction, isNullOrEmptyString, isNullOrUndefined, isString, PushNoDuplicate } from '@kwiz/common';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
4
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
5
5
|
import { commonSizes, useCommonStyles } from '../styles/styles';
|
|
6
6
|
|
|
7
7
|
interface IProps {
|
|
@@ -2,7 +2,7 @@ import { Field, tokens } from "@fluentui/react-components";
|
|
|
2
2
|
import { ArrowMaximizeRegular, ArrowMinimizeRegular, ArrowUploadRegular, CalligraphyPenRegular, DismissRegular } from "@fluentui/react-icons";
|
|
3
3
|
import { debounce, getCSSVariableValue, ImageFileTypes, isElement, isNotEmptyString, isNullOrEmptyArray, isNullOrEmptyString, isNullOrUndefined } from "@kwiz/common";
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import { useAlerts, useElementSize, useStateEX } from "../../helpers
|
|
5
|
+
import { useAlerts, useElementSize, useStateEX } from "../../helpers";
|
|
6
6
|
import { ButtonEX } from "../button";
|
|
7
7
|
import { ColorPickerEx } from "../ColorPickerDialog";
|
|
8
8
|
import { FileUpload } from "../file-upload";
|
package/src/controls/date.tsx
CHANGED
|
@@ -4,8 +4,8 @@ import { TimePicker, TimePickerProps } from '@fluentui/react-timepicker-compat';
|
|
|
4
4
|
import { CalendarCancelRegular } from '@fluentui/react-icons';
|
|
5
5
|
import { isDate } from '@kwiz/common';
|
|
6
6
|
import * as React from 'react';
|
|
7
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
8
|
-
import { useStateEX } from '../helpers
|
|
7
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
8
|
+
import { useStateEX } from '../helpers';
|
|
9
9
|
import { Horizontal } from './horizontal';
|
|
10
10
|
|
|
11
11
|
interface IProps {
|
|
@@ -2,8 +2,8 @@ import { Dialog, DialogBody, DialogContent, DialogSurface, DialogTitle, DialogTr
|
|
|
2
2
|
import { ImageSparkleRegular } from '@fluentui/react-icons';
|
|
3
3
|
import { DiagramOptions, stockUrl } from '@kwiz/common';
|
|
4
4
|
import React from 'react';
|
|
5
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
6
|
-
import { useStateEX } from '../helpers
|
|
5
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
6
|
+
import { useStateEX } from '../helpers';
|
|
7
7
|
import { ButtonEXPrimarySubtle } from './button';
|
|
8
8
|
import { Horizontal } from './horizontal';
|
|
9
9
|
import { Section } from './section';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Dropdown, DropdownProps, makeStyles, mergeClasses, Option } from '@fluentui/react-components';
|
|
2
2
|
import { filterEmptyEntries, firstOrNull, isNullOrUndefined } from '@kwiz/common';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
4
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
5
5
|
|
|
6
6
|
const useStyles = makeStyles({
|
|
7
7
|
root: {
|
|
@@ -2,9 +2,7 @@ import { makeStyles, shorthands, tokens } from "@fluentui/react-components";
|
|
|
2
2
|
import { ArrowUploadRegular } from "@fluentui/react-icons";
|
|
3
3
|
import { isFunction, isNotEmptyArray, isNotEmptyString, isNullOrEmptyString, lastOrNull } from '@kwiz/common';
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import { useDragDropContext } from "../helpers
|
|
6
|
-
import { dropFiles } from "../helpers/drag-drop/exports";
|
|
7
|
-
import { useEffectOnlyOnMount } from "../helpers/hooks";
|
|
5
|
+
import { dropFiles, useDragDropContext, useEffectOnlyOnMount } from "../helpers";
|
|
8
6
|
import { ButtonEX, ButtonEXProps, CompoundButtonEXSecondary } from "./button";
|
|
9
7
|
|
|
10
8
|
const useStyles = makeStyles({
|
|
@@ -33,10 +31,23 @@ interface iProps {
|
|
|
33
31
|
export const FileUpload = React.forwardRef<HTMLButtonElement, (iProps)>((props, ref) => {
|
|
34
32
|
const classes = useStyles();
|
|
35
33
|
const hiddenFileInput = React.useRef(null);
|
|
34
|
+
const onChangeRef = React.useRef(props.onChange);
|
|
35
|
+
const asBase64Ref = React.useRef(props.asBase64);
|
|
36
|
+
|
|
36
37
|
const isMulti = props.allowMultiple === true;
|
|
37
38
|
const icon = props.icon || <ArrowUploadRegular />;
|
|
38
39
|
const title = isNotEmptyString(props.title) ? props.title : `Drop or select ${isMulti ? 'files' : 'file'}`;
|
|
39
40
|
|
|
41
|
+
//keep onChange up to date
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
onChangeRef.current = props.onChange;
|
|
44
|
+
}, [props.onChange]);
|
|
45
|
+
//keep onChange up to date
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
asBase64Ref.current = props.asBase64;
|
|
48
|
+
}, [props.asBase64]);
|
|
49
|
+
|
|
50
|
+
|
|
40
51
|
const onGotFiles = React.useCallback(async (rawFiles: FileList) => {
|
|
41
52
|
let errors: string[] = [];
|
|
42
53
|
let acceptedFiles: File[] = [];
|
|
@@ -66,18 +77,14 @@ export const FileUpload = React.forwardRef<HTMLButtonElement, (iProps)>((props,
|
|
|
66
77
|
}
|
|
67
78
|
|
|
68
79
|
if (isMulti) {
|
|
69
|
-
|
|
70
|
-
props.onChange(acceptedFiles, errors);
|
|
71
|
-
}
|
|
80
|
+
onChangeRef.current?.(acceptedFiles, errors);
|
|
72
81
|
}
|
|
73
82
|
else {
|
|
74
83
|
const fileUploaded = acceptedFiles[0];
|
|
75
|
-
|
|
76
|
-
props.onChange(fileUploaded, errors);
|
|
77
|
-
}
|
|
84
|
+
onChangeRef.current?.(fileUploaded, errors);
|
|
78
85
|
}
|
|
79
86
|
|
|
80
|
-
if (isFunction(
|
|
87
|
+
if (isFunction(asBase64Ref.current)) {
|
|
81
88
|
const filesAs64: base64Result[] = [];
|
|
82
89
|
for (let i = 0; i < (isMulti ? acceptedFiles.length : 1); i++) {
|
|
83
90
|
const currentFile = acceptedFiles[i];
|
|
@@ -95,7 +102,7 @@ export const FileUpload = React.forwardRef<HTMLButtonElement, (iProps)>((props,
|
|
|
95
102
|
else errors.push(`Could not read file ${acceptedFiles[i].name}`);
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
|
-
|
|
105
|
+
asBase64Ref.current?.(filesAs64, errors);
|
|
99
106
|
}
|
|
100
107
|
}, useEffectOnlyOnMount);
|
|
101
108
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export * from './accordion';
|
|
2
|
+
export * from './button';
|
|
3
|
+
export * from './canvas/DrawPad';
|
|
4
|
+
export * from './card';
|
|
5
|
+
export * from './card-list';
|
|
6
|
+
export * from './centered';
|
|
7
|
+
export * from './ColorPickerDialog';
|
|
8
|
+
export * from './date';
|
|
9
|
+
export * from './diagram-picker';
|
|
10
|
+
export * from './divider';
|
|
11
|
+
export * from './dropdown';
|
|
12
|
+
export * from './error-boundary';
|
|
13
|
+
export * from './field-editor';
|
|
14
|
+
export * from './file-upload';
|
|
15
|
+
export * from './horizontal';
|
|
16
|
+
export * from './html-editor/editor';
|
|
17
|
+
export * from './input';
|
|
18
|
+
export * from './kwizoverflow';
|
|
19
|
+
export * from './list';
|
|
20
|
+
export * from './loading';
|
|
21
|
+
export * from './menu';
|
|
22
|
+
export * from './please-wait';
|
|
23
|
+
export * from './progress-bar';
|
|
24
|
+
export * from './prompt';
|
|
25
|
+
export * from './qrcode';
|
|
26
|
+
export * from './search';
|
|
27
|
+
export * from './section';
|
|
28
|
+
export * from './svg';
|
|
29
|
+
export * from './toolbar';
|
|
30
|
+
export * from './vertical';
|
|
31
|
+
export * from './vertical-content';
|
package/src/controls/input.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GriffelStyle, Input, InputOnChangeData, InputProps, Label, Link, makeStyles, mergeClasses, Textarea, TextareaProps } from '@fluentui/react-components';
|
|
2
2
|
import { isFunction, isNotEmptyArray, isNullOrEmptyString, isNullOrNaN, isNullOrUndefined, isNumber } from '@kwiz/common';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
4
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
5
5
|
import { useCommonStyles } from '../styles/styles';
|
|
6
6
|
import { Horizontal } from './horizontal';
|
|
7
7
|
import { MenuEx } from './menu';
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "@fluentui/react-components";
|
|
5
5
|
import { MoreHorizontalFilled } from "@fluentui/react-icons";
|
|
6
6
|
import { isNumber } from '@kwiz/common';
|
|
7
|
-
import { useKWIZFluentContext } from "../helpers/context";
|
|
7
|
+
import { useKWIZFluentContext } from "../helpers/context-internal";
|
|
8
8
|
|
|
9
9
|
interface IProps<ItemType> {
|
|
10
10
|
/** you cannot have a menu with trigger in overflow items. put those in groupWrapper controls before/after rendering children. */
|
package/src/controls/menu.tsx
CHANGED
|
@@ -2,8 +2,8 @@ import { Menu, MenuDivider, MenuGroup, MenuGroupHeader, MenuItem, MenuList, Menu
|
|
|
2
2
|
import { ChevronLeftRegular, ChevronRightRegular } from '@fluentui/react-icons';
|
|
3
3
|
import { IDictionary, isNotEmptyArray, isNotEmptyString, isNullOrEmptyString, isNullOrUndefined, isNumber, isString, isUndefined, jsonClone, stopEvent } from '@kwiz/common';
|
|
4
4
|
import React from 'react';
|
|
5
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
6
|
-
import { useStateEX } from '../helpers
|
|
5
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
6
|
+
import { useStateEX } from '../helpers';
|
|
7
7
|
import { ButtonEX, ButtonEXProps } from './button';
|
|
8
8
|
import { Horizontal } from './horizontal';
|
|
9
9
|
import { Search } from './search';
|
package/src/controls/prompt.tsx
CHANGED
|
@@ -2,8 +2,8 @@ import { Dialog, DialogActions, DialogBody, DialogContent, DialogModalType, Dial
|
|
|
2
2
|
import { DismissRegular } from '@fluentui/react-icons';
|
|
3
3
|
import { isNotEmptyArray, isNullOrEmptyString, noops, PushNoDuplicate, RemoveItemFromArr, stopEvent } from '@kwiz/common';
|
|
4
4
|
import React from 'react';
|
|
5
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
6
|
-
import { useKeyDown } from '../helpers/hooks';
|
|
5
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
6
|
+
import { useKeyDown } from '../helpers/hooks-events';
|
|
7
7
|
import { ButtonEX, ButtonEXProps, ButtonEXSecondary } from './button';
|
|
8
8
|
|
|
9
9
|
export interface IPrompterProps {
|
package/src/controls/search.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { DismissRegular, SearchRegular } from "@fluentui/react-icons";
|
|
|
3
3
|
import { debounce, isFunction, isNullOrEmptyString, isUndefined } from '@kwiz/common';
|
|
4
4
|
import React, { useState } from 'react';
|
|
5
5
|
import { GetLogger } from '../_modules/config';
|
|
6
|
-
import { useStateEX } from '../helpers
|
|
6
|
+
import { useStateEX } from '../helpers';
|
|
7
7
|
import { mixins } from '../styles/styles';
|
|
8
8
|
const logger = GetLogger("Search");
|
|
9
9
|
|
package/src/controls/section.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { makeStyles, mergeClasses, Portal, tokens } from '@fluentui/react-components';
|
|
2
2
|
import { isFunction, isNotEmptyArray } from '@kwiz/common';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { useKWIZFluentContext } from '../helpers/context';
|
|
4
|
+
import { useKWIZFluentContext } from '../helpers/context-internal';
|
|
5
5
|
import { KnownClassNames, mixins, useCommonStyles } from '../styles/styles';
|
|
6
6
|
|
|
7
7
|
const useStyles = makeStyles({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { makeStyles, mergeClasses } from '@fluentui/react-components';
|
|
2
2
|
import { isNotEmptyArray } from '@kwiz/common';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { useWindowSize } from '../helpers
|
|
4
|
+
import { useWindowSize } from '../helpers';
|
|
5
5
|
|
|
6
6
|
const useStyles = makeStyles({
|
|
7
7
|
verticalContainer: {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { IDictionary, isNotEmptyArray, isNullOrEmptyString, jsonClone, objectsEqual } from "@kwiz/common";
|
|
2
|
+
import { useCallback, useEffect } from "react";
|
|
3
|
+
import { IPrompterProps, Prompter } from "../controls/prompt";
|
|
4
|
+
import { useEffectOnlyOnMount, useStateEX } from "./hooks";
|
|
5
|
+
|
|
6
|
+
export interface iBlockNav {
|
|
7
|
+
setMessage: (id: string, message?: string) => void;
|
|
8
|
+
onNav: (nav: () => void) => void;
|
|
9
|
+
navPrompt?: JSX.Element;
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
/** set block message if you want to block nav.
|
|
13
|
+
* - call setMessage to add a blocker message
|
|
14
|
+
* - call onNav when you have internal navigation (open / close popups)
|
|
15
|
+
* - render the navPrompt control to your page
|
|
16
|
+
* FYI for page unload, most modern browsers won't show your message but a generic one instead. */
|
|
17
|
+
export function useBlockNav(): iBlockNav {
|
|
18
|
+
const [, setBlockNavMessages, blockNavMessagesRef] = useStateEX<IDictionary<string>>({});
|
|
19
|
+
const [_prompt, setPrompt] = useStateEX<IPrompterProps>(null);
|
|
20
|
+
|
|
21
|
+
const getMessagesArr = useCallback(() => {
|
|
22
|
+
return Object.keys(blockNavMessagesRef.current).map(id => blockNavMessagesRef.current[id]);
|
|
23
|
+
}, useEffectOnlyOnMount);
|
|
24
|
+
|
|
25
|
+
const getMessages = useCallback(() => {
|
|
26
|
+
return getMessagesArr().join();
|
|
27
|
+
}, useEffectOnlyOnMount);
|
|
28
|
+
|
|
29
|
+
const onNav = useCallback((nav: () => void) => {
|
|
30
|
+
let messages = getMessagesArr();
|
|
31
|
+
if (isNotEmptyArray(messages)) {
|
|
32
|
+
//need to release react to re-render the prompt
|
|
33
|
+
window.setTimeout(() => {
|
|
34
|
+
//prompt, if ok - clear messages and nav.
|
|
35
|
+
setPrompt({
|
|
36
|
+
okButtonText: "Leave",
|
|
37
|
+
cancelButtonText: "Cancel",
|
|
38
|
+
title: "Leave page?",
|
|
39
|
+
children: messages.length > 1
|
|
40
|
+
? <ul>
|
|
41
|
+
{messages.map((m, i) => <li key={`m${i}`}>{m}</li>)}
|
|
42
|
+
</ul>
|
|
43
|
+
: <p>{messages[0]}</p>,
|
|
44
|
+
onCancel: () => setPrompt(null),
|
|
45
|
+
onOK: () => {
|
|
46
|
+
setPrompt(null);
|
|
47
|
+
setBlockNavMessages({});//clear messages
|
|
48
|
+
nav();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}, 1);
|
|
52
|
+
}
|
|
53
|
+
else nav();
|
|
54
|
+
}, useEffectOnlyOnMount);
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
function handleBeforeUnload(e: BeforeUnloadEvent) {
|
|
59
|
+
//todo: use blockMessageRef.current so that we don't have to re-register every time message changes.
|
|
60
|
+
//otherwise we would have to add blockMessage as a dependency for this useEffect
|
|
61
|
+
const message = getMessages();
|
|
62
|
+
if (!isNullOrEmptyString(message)) {
|
|
63
|
+
e.preventDefault();
|
|
64
|
+
e.returnValue = message;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Add event listener
|
|
68
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
69
|
+
// Remove event listener on cleanup
|
|
70
|
+
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
71
|
+
}, useEffectOnlyOnMount);
|
|
72
|
+
return {
|
|
73
|
+
setMessage: (id: string, message?: string) => {
|
|
74
|
+
let current = jsonClone(blockNavMessagesRef.current);
|
|
75
|
+
if (isNullOrEmptyString(message))
|
|
76
|
+
delete current[id];
|
|
77
|
+
else current[id] = message;
|
|
78
|
+
if (!objectsEqual(current, blockNavMessagesRef.current))
|
|
79
|
+
setBlockNavMessages(current);
|
|
80
|
+
},
|
|
81
|
+
// clearMessages: () => {
|
|
82
|
+
// setBlockNavMessages({});
|
|
83
|
+
// },
|
|
84
|
+
// getMessages,
|
|
85
|
+
// getMessagesArr,
|
|
86
|
+
onNav,
|
|
87
|
+
navPrompt: _prompt ? <Prompter {..._prompt} /> : undefined
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { makeStyles } from "@fluentui/react-components";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
export interface iKWIZFluentContext {
|
|
5
|
+
/**
|
|
6
|
+
* Where the portal children are mounted on DOM
|
|
7
|
+
*
|
|
8
|
+
* @default a new element on document.body without any styling
|
|
9
|
+
*/
|
|
10
|
+
mountNode?: HTMLElement | null | {
|
|
11
|
+
element?: HTMLElement | null;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Controls the colors and borders of the input.
|
|
16
|
+
*
|
|
17
|
+
* @default 'underline'
|
|
18
|
+
*/
|
|
19
|
+
inputAppearance?: 'outline' | 'underline' | 'filled-darker' | 'filled-lighter';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A button can be rounded, circular, or square.
|
|
23
|
+
*
|
|
24
|
+
* @default 'rounded'
|
|
25
|
+
*/
|
|
26
|
+
buttonShape?: 'rounded' | 'circular' | 'square';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const useContextStyles = makeStyles({
|
|
30
|
+
root: {
|
|
31
|
+
"& *": {
|
|
32
|
+
scrollbarWidth: "thin"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
export function useKWIZFluentContextProvider(options: {
|
|
37
|
+
root?: React.MutableRefObject<HTMLDivElement>;
|
|
38
|
+
ctx?: iKWIZFluentContext;
|
|
39
|
+
}) {
|
|
40
|
+
const classes = useContextStyles();
|
|
41
|
+
let v: iKWIZFluentContext = options && options.ctx || {};
|
|
42
|
+
const [kwizFluentContext, setKwizFluentContext] = useState<iKWIZFluentContext>(v);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
options.root?.current?.classList.add(...classes.root.split(' '));
|
|
45
|
+
// ref only updates in useEffect, not in useMemo or anything else.
|
|
46
|
+
// we need to set it into state so it will trigger a ui update
|
|
47
|
+
setKwizFluentContext({
|
|
48
|
+
...v,
|
|
49
|
+
mountNode: options.root.current
|
|
50
|
+
});
|
|
51
|
+
}, [options.root]);
|
|
52
|
+
return kwizFluentContext;
|
|
53
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isNullOrUndefined } from "@kwiz/common";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { iKWIZFluentContext } from "./context-export";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
//create context
|
|
7
|
+
export const KWIZFluentContext = React.createContext<iKWIZFluentContext>(null);
|
|
8
|
+
//use context from within controls
|
|
9
|
+
export function useKWIZFluentContext() {
|
|
10
|
+
let ctx = React.useContext(KWIZFluentContext) || {};
|
|
11
|
+
//set defaults
|
|
12
|
+
if (isNullOrUndefined(ctx.inputAppearance))
|
|
13
|
+
ctx.inputAppearance = "underline";
|
|
14
|
+
if (isNullOrUndefined(ctx.buttonShape))
|
|
15
|
+
ctx.buttonShape = "circular";
|
|
16
|
+
return ctx;
|
|
17
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { mergeClasses } from "@fluentui/react-components";
|
|
2
2
|
import { useDragDropContext } from "./drag-drop-context";
|
|
3
|
-
import { iDraggableProps, iDraggedItemType } from "./
|
|
4
|
-
import { iDroppableProps } from "./use-droppable";
|
|
3
|
+
import { iDraggableProps, iDraggedItemType, iDroppableProps } from "./drag-drop.types";
|
|
5
4
|
|
|
6
5
|
interface one<DragItemType extends iDraggedItemType<string>> {
|
|
7
6
|
dragInfo: iDraggableProps<DragItemType>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import { iDragDropContext } from "./drag-drop.types";
|
|
3
|
+
|
|
4
|
+
//create context
|
|
5
|
+
export const DragDropContext = React.createContext<iDragDropContext>(null);
|
|
6
|
+
//use context from within controls
|
|
7
|
+
export function useDragDropContextInternal() {
|
|
8
|
+
const dragDropContext = useContext(DragDropContext);
|
|
9
|
+
return dragDropContext;
|
|
10
|
+
}
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import { isNullOrUndefined } from "@kwiz/common";
|
|
2
|
-
import React
|
|
2
|
+
import React from "react";
|
|
3
3
|
import { DndProvider } from "react-dnd";
|
|
4
4
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
|
5
5
|
import { useStateEX } from "../hooks";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
6
|
+
import { DragDropContext, useDragDropContextInternal } from "./drag-drop-context-internal";
|
|
7
|
+
import { iDragDropContext, iDraggableProps, iDraggedItemType, iDroppableProps } from "./drag-drop.types";
|
|
8
|
+
import { useDraggable } from "./use-draggable";
|
|
9
|
+
import { useDroppable } from "./use-droppable";
|
|
8
10
|
|
|
9
|
-
export interface iDragDropContext {
|
|
10
|
-
isDragging: boolean;
|
|
11
|
-
dragItem: iDraggedItemType<string>;
|
|
12
|
-
setDragItem: (value: iDraggedItemType<string>) => void;
|
|
13
|
-
}
|
|
14
|
-
//create context
|
|
15
|
-
export const DragDropContext = React.createContext<iDragDropContext>(null);
|
|
16
|
-
//use context from within controls
|
|
17
|
-
export function useDragDropContextInternal() {
|
|
18
|
-
const dragDropContext = useContext(DragDropContext);
|
|
19
|
-
return dragDropContext;
|
|
20
|
-
}
|
|
21
11
|
export function useDragDropContext<
|
|
22
12
|
DragItemType extends iDraggedItemType<string> = never,
|
|
23
13
|
DropInfoType extends iDroppableProps<string, any> = never
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface iDraggedItemType<DragType extends string> {
|
|
2
|
+
type: DragType;
|
|
3
|
+
}
|
|
4
|
+
export interface iDraggableProps<ItemType extends iDraggedItemType<string>> {
|
|
5
|
+
item: ItemType;
|
|
6
|
+
onBeginDrag?: () => void;
|
|
7
|
+
onEndDrag?: (dropResult: any) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface iDroppableProps<DropTypes extends string, ItemTypes extends iDraggedItemType<DropTypes>> {
|
|
11
|
+
acceptTypes: DropTypes[];
|
|
12
|
+
onItemDrop: (item: ItemTypes) => void;
|
|
13
|
+
onHover?: (item: ItemTypes) => void;
|
|
14
|
+
onDrop?: () => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface iDragDropContext {
|
|
18
|
+
isDragging: boolean;
|
|
19
|
+
dragItem: iDraggedItemType<string>;
|
|
20
|
+
setDragItem: (value: iDraggedItemType<string>) => void;
|
|
21
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { NativeTypes } from 'react-dnd-html5-backend';
|
|
2
|
-
import { iDraggedItemType } from './
|
|
3
|
-
import { iDroppableProps } from './use-droppable';
|
|
2
|
+
import { iDraggedItemType, iDroppableProps } from './drag-drop.types';
|
|
4
3
|
|
|
5
4
|
export { DragDropContainer } from './drag-drop-container';
|
|
6
5
|
export { DragDropContextProvider, useDragDropContext } from "./drag-drop-context";
|
|
7
|
-
export type { iDraggedItemType } from "./
|
|
8
|
-
export type { iDroppableProps } from "./use-droppable";
|
|
6
|
+
export type { iDraggedItemType, iDroppableProps } from "./drag-drop.types";
|
|
9
7
|
|
|
10
8
|
type fileNativeType = typeof NativeTypes.FILE;
|
|
11
9
|
interface dragFiles extends iDraggedItemType<fileNativeType> {
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
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
|
-
}
|
|
3
|
+
import { useDragDropContextInternal } from './drag-drop-context-internal';
|
|
4
|
+
import { iDraggableProps, iDraggedItemType } from './drag-drop.types';
|
|
13
5
|
|
|
14
6
|
export function useDraggable<ItemType extends iDraggedItemType<string>>(props?: iDraggableProps<ItemType>): {
|
|
15
7
|
isDragging: boolean;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { ConnectDropTarget, DropTargetMonitor, useDrop } from 'react-dnd';
|
|
2
|
-
import { iDraggedItemType } from './
|
|
2
|
+
import { iDraggedItemType, iDroppableProps } from './drag-drop.types';
|
|
3
3
|
|
|
4
|
-
export
|
|
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>): {
|
|
4
|
+
export function useDroppable<DropType extends string, ItemType extends iDraggedItemType<DropType>>(props?: iDroppableProps<DropType, ItemType>): {
|
|
12
5
|
canDrop: boolean;
|
|
13
6
|
isOver: boolean;
|
|
14
7
|
dropRef: ConnectDropTarget;
|
|
@@ -43,6 +36,4 @@ function useDroppable<DropType extends string, ItemType extends iDraggedItemType
|
|
|
43
36
|
isOver,
|
|
44
37
|
dropRef,
|
|
45
38
|
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default useDroppable;
|
|
39
|
+
}
|