@kwiz/fluentui 1.0.73 → 1.0.75
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 +24 -24
- package/LICENSE +21 -21
- package/README.md +53 -53
- package/dist/@types/forwardRef.d.ts +0 -0
- package/dist/@types/forwardRef.js +1 -0
- package/dist/@types/forwardRef.js.map +1 -0
- package/dist/controls/error-boundary copy.d.ts +23 -0
- package/dist/controls/error-boundary copy.js +33 -0
- package/dist/controls/error-boundary copy.js.map +1 -0
- package/dist/controls/menu.js +2 -2
- package/dist/controls/menu.js.map +1 -1
- package/dist/controls/search.js +19 -11
- package/dist/controls/search.js.map +1 -1
- package/dist/controls/svg.js +21 -21
- package/dist/controls/svg.js.map +1 -1
- package/dist/helpers/common.d.ts +4 -0
- package/dist/helpers/common.js +2 -0
- package/dist/helpers/common.js.map +1 -0
- package/dist/helpers/context.d.ts +26 -0
- package/dist/helpers/context.js +15 -0
- package/dist/helpers/context.js.map +1 -0
- package/dist/helpers/drag-drop/exports.d.ts +12 -0
- package/dist/helpers/drag-drop/exports.js +3 -0
- package/dist/helpers/drag-drop/exports.js.map +1 -0
- package/dist/helpers/exports.d.ts +7 -0
- package/dist/helpers/exports.js +8 -0
- package/dist/helpers/exports.js.map +1 -0
- package/dist/helpers/use-editable-control.d.ts +1 -1
- package/dist/helpers/use-editable-control.js.map +1 -1
- package/package.json +85 -84
- package/src/_modules/config.ts +9 -9
- package/src/_modules/constants.ts +3 -3
- package/src/controls/ColorPickerDialog.tsx +83 -83
- package/src/controls/accordion.tsx +62 -62
- package/src/controls/button.tsx +180 -180
- package/src/controls/canvas/CustomEventTargetBase.ts +32 -32
- package/src/controls/canvas/DrawPad.tsx +296 -296
- package/src/controls/canvas/DrawPadManager.ts +694 -694
- package/src/controls/canvas/bezier.ts +109 -109
- package/src/controls/canvas/point.ts +44 -44
- package/src/controls/card-list.tsx +31 -31
- package/src/controls/card.tsx +77 -77
- package/src/controls/centered.tsx +14 -14
- package/src/controls/date.tsx +87 -87
- package/src/controls/diagram-picker.tsx +96 -96
- package/src/controls/divider.tsx +15 -15
- package/src/controls/dropdown.tsx +66 -66
- package/src/controls/error-boundary.tsx +41 -41
- package/src/controls/field-editor.tsx +42 -42
- package/src/controls/file-upload.tsx +155 -155
- package/src/controls/horizontal.tsx +48 -48
- package/src/controls/html-editor/editor.tsx +182 -182
- package/src/controls/index.ts +33 -33
- package/src/controls/input.tsx +160 -160
- package/src/controls/kwizoverflow.tsx +106 -106
- package/src/controls/list.tsx +119 -119
- package/src/controls/loading.tsx +10 -10
- package/src/controls/menu.tsx +173 -173
- package/src/controls/merge-text.tsx +126 -126
- package/src/controls/please-wait.tsx +32 -32
- package/src/controls/progress-bar.tsx +109 -109
- package/src/controls/prompt.tsx +121 -121
- package/src/controls/qrcode.tsx +36 -36
- package/src/controls/search.tsx +71 -61
- package/src/controls/section.tsx +133 -133
- package/src/controls/svg.tsx +138 -138
- package/src/controls/toolbar.tsx +46 -46
- package/src/controls/vertical-content.tsx +49 -49
- package/src/controls/vertical.tsx +42 -42
- package/src/helpers/block-nav.tsx +88 -88
- package/src/helpers/context-const.ts +29 -29
- package/src/helpers/context-export.tsx +77 -77
- package/src/helpers/context-internal.ts +13 -13
- package/src/helpers/drag-drop/drag-drop-container.tsx +53 -53
- package/src/helpers/drag-drop/drag-drop-context-internal.tsx +9 -9
- package/src/helpers/drag-drop/drag-drop-context.tsx +61 -61
- package/src/helpers/drag-drop/drag-drop.types.ts +21 -21
- package/src/helpers/drag-drop/index.ts +12 -12
- package/src/helpers/drag-drop/readme.md +75 -75
- package/src/helpers/drag-drop/use-draggable.ts +47 -47
- package/src/helpers/drag-drop/use-droppable.ts +38 -38
- package/src/helpers/forwardRef.ts +7 -7
- package/src/helpers/hooks-events.ts +149 -149
- package/src/helpers/hooks.tsx +141 -141
- package/src/helpers/index.ts +8 -8
- package/src/helpers/use-alerts.tsx +74 -74
- package/src/helpers/use-editable-control.tsx +37 -37
- package/src/helpers/use-toast.tsx +29 -29
- package/src/index.ts +2 -2
- package/src/styles/index.ts +1 -1
- package/src/styles/styles.ts +104 -104
- package/src/styles/theme.ts +90 -90
@@ -1,48 +1,48 @@
|
|
1
|
-
import { useEffect } from 'react';
|
2
|
-
import { ConnectDragSource, DragSourceMonitor, useDrag } from 'react-dnd';
|
3
|
-
import { useDragDropContextInternal } from './drag-drop-context-internal';
|
4
|
-
import { iDraggableProps, iDraggedItemType } from './drag-drop.types';
|
5
|
-
|
6
|
-
export function useDraggable<ItemType extends iDraggedItemType<string>>(props?: iDraggableProps<ItemType>): {
|
7
|
-
isDragging: boolean;
|
8
|
-
dragRef: ConnectDragSource
|
9
|
-
} {
|
10
|
-
const {
|
11
|
-
item,
|
12
|
-
onBeginDrag,
|
13
|
-
onEndDrag,
|
14
|
-
} = props || {
|
15
|
-
item: {
|
16
|
-
type: "~invalid~"
|
17
|
-
}
|
18
|
-
};
|
19
|
-
|
20
|
-
const dragDropContext = useDragDropContextInternal();
|
21
|
-
|
22
|
-
const [{ isDragging }, dragRef] = useDrag(
|
23
|
-
() => ({
|
24
|
-
type: item.type,
|
25
|
-
item,
|
26
|
-
collect: (monitor: DragSourceMonitor) => ({
|
27
|
-
isDragging: monitor.isDragging(),
|
28
|
-
}),
|
29
|
-
end: (item, monitor) => {
|
30
|
-
dragDropContext.setDragItem(null);
|
31
|
-
onEndDrag && onEndDrag(monitor.getDropResult());
|
32
|
-
},
|
33
|
-
}),
|
34
|
-
[item, item.type]
|
35
|
-
);
|
36
|
-
|
37
|
-
useEffect(() => {
|
38
|
-
if (isDragging) {
|
39
|
-
dragDropContext.setDragItem(item);
|
40
|
-
onBeginDrag && onBeginDrag();
|
41
|
-
}
|
42
|
-
}, [isDragging, onBeginDrag])
|
43
|
-
|
44
|
-
return {
|
45
|
-
isDragging,
|
46
|
-
dragRef,
|
47
|
-
};
|
1
|
+
import { useEffect } from 'react';
|
2
|
+
import { ConnectDragSource, DragSourceMonitor, useDrag } from 'react-dnd';
|
3
|
+
import { useDragDropContextInternal } from './drag-drop-context-internal';
|
4
|
+
import { iDraggableProps, iDraggedItemType } from './drag-drop.types';
|
5
|
+
|
6
|
+
export function useDraggable<ItemType extends iDraggedItemType<string>>(props?: iDraggableProps<ItemType>): {
|
7
|
+
isDragging: boolean;
|
8
|
+
dragRef: ConnectDragSource
|
9
|
+
} {
|
10
|
+
const {
|
11
|
+
item,
|
12
|
+
onBeginDrag,
|
13
|
+
onEndDrag,
|
14
|
+
} = props || {
|
15
|
+
item: {
|
16
|
+
type: "~invalid~"
|
17
|
+
}
|
18
|
+
};
|
19
|
+
|
20
|
+
const dragDropContext = useDragDropContextInternal();
|
21
|
+
|
22
|
+
const [{ isDragging }, dragRef] = useDrag(
|
23
|
+
() => ({
|
24
|
+
type: item.type,
|
25
|
+
item,
|
26
|
+
collect: (monitor: DragSourceMonitor) => ({
|
27
|
+
isDragging: monitor.isDragging(),
|
28
|
+
}),
|
29
|
+
end: (item, monitor) => {
|
30
|
+
dragDropContext.setDragItem(null);
|
31
|
+
onEndDrag && onEndDrag(monitor.getDropResult());
|
32
|
+
},
|
33
|
+
}),
|
34
|
+
[item, item.type]
|
35
|
+
);
|
36
|
+
|
37
|
+
useEffect(() => {
|
38
|
+
if (isDragging) {
|
39
|
+
dragDropContext.setDragItem(item);
|
40
|
+
onBeginDrag && onBeginDrag();
|
41
|
+
}
|
42
|
+
}, [isDragging, onBeginDrag])
|
43
|
+
|
44
|
+
return {
|
45
|
+
isDragging,
|
46
|
+
dragRef,
|
47
|
+
};
|
48
48
|
}
|
@@ -1,39 +1,39 @@
|
|
1
|
-
import { ConnectDropTarget, DropTargetMonitor, useDrop } from 'react-dnd';
|
2
|
-
import { iDraggedItemType, iDroppableProps } from './drag-drop.types';
|
3
|
-
|
4
|
-
export function useDroppable<DropType extends string, ItemType extends iDraggedItemType<DropType>>(props?: iDroppableProps<DropType, ItemType>): {
|
5
|
-
canDrop: boolean;
|
6
|
-
isOver: boolean;
|
7
|
-
dropRef: ConnectDropTarget;
|
8
|
-
} {
|
9
|
-
const {
|
10
|
-
acceptTypes,
|
11
|
-
onItemDrop,
|
12
|
-
onHover,
|
13
|
-
onDrop,
|
14
|
-
} = props || {
|
15
|
-
acceptTypes: [],
|
16
|
-
onItemDrop: () => { }
|
17
|
-
};
|
18
|
-
|
19
|
-
const [{ canDrop, isOver }, dropRef] = useDrop({
|
20
|
-
accept: acceptTypes,
|
21
|
-
drop: (item: ItemType) => {
|
22
|
-
onItemDrop(item);
|
23
|
-
onDrop?.();
|
24
|
-
},
|
25
|
-
hover: (item: ItemType) => {
|
26
|
-
onHover?.(item);
|
27
|
-
},
|
28
|
-
collect: (monitor: DropTargetMonitor) => ({
|
29
|
-
canDrop: monitor.canDrop(),
|
30
|
-
isOver: monitor.isOver(),
|
31
|
-
}),
|
32
|
-
});
|
33
|
-
|
34
|
-
return {
|
35
|
-
canDrop,
|
36
|
-
isOver,
|
37
|
-
dropRef,
|
38
|
-
};
|
1
|
+
import { ConnectDropTarget, DropTargetMonitor, useDrop } from 'react-dnd';
|
2
|
+
import { iDraggedItemType, iDroppableProps } from './drag-drop.types';
|
3
|
+
|
4
|
+
export function useDroppable<DropType extends string, ItemType extends iDraggedItemType<DropType>>(props?: iDroppableProps<DropType, ItemType>): {
|
5
|
+
canDrop: boolean;
|
6
|
+
isOver: boolean;
|
7
|
+
dropRef: ConnectDropTarget;
|
8
|
+
} {
|
9
|
+
const {
|
10
|
+
acceptTypes,
|
11
|
+
onItemDrop,
|
12
|
+
onHover,
|
13
|
+
onDrop,
|
14
|
+
} = props || {
|
15
|
+
acceptTypes: [],
|
16
|
+
onItemDrop: () => { }
|
17
|
+
};
|
18
|
+
|
19
|
+
const [{ canDrop, isOver }, dropRef] = useDrop({
|
20
|
+
accept: acceptTypes,
|
21
|
+
drop: (item: ItemType) => {
|
22
|
+
onItemDrop(item);
|
23
|
+
onDrop?.();
|
24
|
+
},
|
25
|
+
hover: (item: ItemType) => {
|
26
|
+
onHover?.(item);
|
27
|
+
},
|
28
|
+
collect: (monitor: DropTargetMonitor) => ({
|
29
|
+
canDrop: monitor.canDrop(),
|
30
|
+
isOver: monitor.isOver(),
|
31
|
+
}),
|
32
|
+
});
|
33
|
+
|
34
|
+
return {
|
35
|
+
canDrop,
|
36
|
+
isOver,
|
37
|
+
dropRef,
|
38
|
+
};
|
39
39
|
}
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
//need to redeclare to support forward ref with generic types
|
3
|
-
declare module "react" {
|
4
|
-
function forwardRef<T, P = {}>(
|
5
|
-
render: (props: P, ref: React.Ref<T>) => React.JSX.Element | null
|
6
|
-
): (props: P & React.RefAttributes<T>) => React.JSX.Element | null;
|
7
|
-
}
|
1
|
+
import React from 'react';
|
2
|
+
//need to redeclare to support forward ref with generic types
|
3
|
+
declare module "react" {
|
4
|
+
function forwardRef<T, P = {}>(
|
5
|
+
render: (props: P, ref: React.Ref<T>) => React.JSX.Element | null
|
6
|
+
): (props: P & React.RefAttributes<T>) => React.JSX.Element | null;
|
7
|
+
}
|
@@ -1,150 +1,150 @@
|
|
1
|
-
import { isDebug, isFunction } from "@kwiz/common";
|
2
|
-
import { MutableRefObject, useEffect, useRef, useState } from "react";
|
3
|
-
import { KnownClassNames } from "../styles/styles";
|
4
|
-
import { useEffectOnlyOnMount } from "./hooks";
|
5
|
-
|
6
|
-
export function useTrackFocus<elmType extends HTMLElement>(props: { onFocus: () => void, onLoseFocus: () => void, ref?: MutableRefObject<elmType> }) {
|
7
|
-
const wrapperDiv: MutableRefObject<elmType> = props.ref || useRef<HTMLDivElement>(null) as any;
|
8
|
-
useEffect(() => {
|
9
|
-
function focusIn(e: FocusEvent) {
|
10
|
-
let elm = e.target as HTMLElement;//document.activeElement;
|
11
|
-
if (wrapperDiv.current) {
|
12
|
-
while (elm && elm !== wrapperDiv.current) {
|
13
|
-
elm = elm.parentElement;
|
14
|
-
}
|
15
|
-
} else elm = null;
|
16
|
-
if (wrapperDiv.current && elm === wrapperDiv.current) props.onFocus();
|
17
|
-
else props.onLoseFocus();
|
18
|
-
}
|
19
|
-
|
20
|
-
if (wrapperDiv.current) {
|
21
|
-
if (wrapperDiv.current) wrapperDiv.current.tabIndex = 1;
|
22
|
-
window.addEventListener("focusin", focusIn);
|
23
|
-
// Remove event listener on cleanup
|
24
|
-
return () => window.removeEventListener("focusin", focusIn);
|
25
|
-
}
|
26
|
-
}, [wrapperDiv.current]);
|
27
|
-
return wrapperDiv;
|
28
|
-
}
|
29
|
-
export function useWindowSize() {
|
30
|
-
// Initialize state with undefined width/height so server and client renders match
|
31
|
-
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
|
32
|
-
const [windowSize, setWindowSize] = useState<{
|
33
|
-
width: number,
|
34
|
-
height: number
|
35
|
-
}>({
|
36
|
-
width: undefined,
|
37
|
-
height: undefined
|
38
|
-
});
|
39
|
-
useEffect(() => {
|
40
|
-
// Handler to call on window resize
|
41
|
-
function handleResize() {
|
42
|
-
|
43
|
-
// Set window width/height to state
|
44
|
-
setWindowSize({
|
45
|
-
width: window.innerWidth,
|
46
|
-
height: window.innerHeight
|
47
|
-
});
|
48
|
-
}
|
49
|
-
// Add event listener
|
50
|
-
window.addEventListener("resize", handleResize);
|
51
|
-
// Call handler right away so state gets updated with initial window size
|
52
|
-
handleResize();
|
53
|
-
// Remove event listener on cleanup
|
54
|
-
return () => window.removeEventListener("resize", handleResize);
|
55
|
-
}, useEffectOnlyOnMount);
|
56
|
-
return windowSize;
|
57
|
-
}
|
58
|
-
export function useElementSize(elm: HTMLElement) {
|
59
|
-
// Initialize state with undefined width/height so server and client renders match
|
60
|
-
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
|
61
|
-
const [elmSize, setELmSize] = useState<{
|
62
|
-
width: number,
|
63
|
-
height: number
|
64
|
-
}>({
|
65
|
-
width: undefined,
|
66
|
-
height: undefined
|
67
|
-
});
|
68
|
-
useEffect(() => {
|
69
|
-
if (elm) {
|
70
|
-
// Handler to call on elm resize
|
71
|
-
function handleResize() {
|
72
|
-
// Set elm width/height to state
|
73
|
-
setELmSize({
|
74
|
-
width: (elm instanceof Window) ? elm.innerWidth : elm.clientWidth,
|
75
|
-
height: (elm instanceof Window) ? elm.innerHeight : elm.clientHeight,
|
76
|
-
});
|
77
|
-
}
|
78
|
-
// Add event listener
|
79
|
-
const observer = new ResizeObserver(handleResize);
|
80
|
-
observer.observe(elm);
|
81
|
-
// Call handler right away so state gets updated with initial elm size
|
82
|
-
handleResize();
|
83
|
-
// Remove event listener on cleanup
|
84
|
-
return () => observer.disconnect();
|
85
|
-
}
|
86
|
-
}, [elm]);
|
87
|
-
return elmSize;
|
88
|
-
}
|
89
|
-
export function useIsInPrint() {
|
90
|
-
// Initialize state with media query
|
91
|
-
const [printMode, setPrintMode] = useState<boolean>(window.matchMedia ? window.matchMedia('print').matches : false);
|
92
|
-
useEffect(() => {
|
93
|
-
if (printMode)
|
94
|
-
document.body.classList.add(KnownClassNames.print);
|
95
|
-
else
|
96
|
-
document.body.classList.remove(KnownClassNames.print);
|
97
|
-
}, [printMode]);
|
98
|
-
|
99
|
-
useEffect(() => {
|
100
|
-
const forcePrintOn = () => setPrintMode(true);
|
101
|
-
const forcePrintOff = () => setPrintMode(false);
|
102
|
-
|
103
|
-
function printDebugHelper(e: KeyboardEvent) {
|
104
|
-
if (e.ctrlKey && e.shiftKey && e.altKey) {
|
105
|
-
if (e.key.toLocaleLowerCase() === "q") {
|
106
|
-
forcePrintOff();
|
107
|
-
}
|
108
|
-
else {
|
109
|
-
console.warn('forced print mode - to exit refresh to ctrl+shift+alt+q');
|
110
|
-
forcePrintOn();
|
111
|
-
}
|
112
|
-
}
|
113
|
-
}
|
114
|
-
|
115
|
-
// Add event listener
|
116
|
-
window.addEventListener("beforeprint", forcePrintOn);
|
117
|
-
window.addEventListener("afterprint", forcePrintOff);
|
118
|
-
if (isDebug())
|
119
|
-
window.addEventListener("keydown", printDebugHelper);
|
120
|
-
// Remove event listener on cleanup
|
121
|
-
return () => {
|
122
|
-
window.removeEventListener("beforeprint", forcePrintOn);
|
123
|
-
window.removeEventListener("afterprint", forcePrintOff);
|
124
|
-
if (isDebug())
|
125
|
-
window.removeEventListener("keydown", printDebugHelper);
|
126
|
-
};
|
127
|
-
}, useEffectOnlyOnMount);
|
128
|
-
return printMode;
|
129
|
-
}
|
130
|
-
|
131
|
-
export function useKeyDown(options: {
|
132
|
-
//default use document
|
133
|
-
elm?: HTMLElement | Document;
|
134
|
-
onEnter?: (e: KeyboardEvent) => void;
|
135
|
-
onEscape?: (e: KeyboardEvent) => void;
|
136
|
-
onKeyDown?: (e: KeyboardEvent) => void;
|
137
|
-
}) {
|
138
|
-
let elm = options.elm || document;
|
139
|
-
|
140
|
-
useEffect(() => {
|
141
|
-
let handler = (e: KeyboardEvent) => {
|
142
|
-
if (e.key === "Enter" && isFunction(options.onEnter)) options.onEnter(e);
|
143
|
-
else if (e.key === "Escape" && isFunction(options.onEscape)) options.onEscape(e);
|
144
|
-
if (isFunction(options.onKeyDown))
|
145
|
-
options.onKeyDown(e);
|
146
|
-
};
|
147
|
-
elm.addEventListener("keydown", handler);
|
148
|
-
return () => elm.removeEventListener("keydown", handler);
|
149
|
-
}, [elm, options.onEnter, options.onEscape, options.onKeyDown]);
|
1
|
+
import { isDebug, isFunction } from "@kwiz/common";
|
2
|
+
import { MutableRefObject, useEffect, useRef, useState } from "react";
|
3
|
+
import { KnownClassNames } from "../styles/styles";
|
4
|
+
import { useEffectOnlyOnMount } from "./hooks";
|
5
|
+
|
6
|
+
export function useTrackFocus<elmType extends HTMLElement>(props: { onFocus: () => void, onLoseFocus: () => void, ref?: MutableRefObject<elmType> }) {
|
7
|
+
const wrapperDiv: MutableRefObject<elmType> = props.ref || useRef<HTMLDivElement>(null) as any;
|
8
|
+
useEffect(() => {
|
9
|
+
function focusIn(e: FocusEvent) {
|
10
|
+
let elm = e.target as HTMLElement;//document.activeElement;
|
11
|
+
if (wrapperDiv.current) {
|
12
|
+
while (elm && elm !== wrapperDiv.current) {
|
13
|
+
elm = elm.parentElement;
|
14
|
+
}
|
15
|
+
} else elm = null;
|
16
|
+
if (wrapperDiv.current && elm === wrapperDiv.current) props.onFocus();
|
17
|
+
else props.onLoseFocus();
|
18
|
+
}
|
19
|
+
|
20
|
+
if (wrapperDiv.current) {
|
21
|
+
if (wrapperDiv.current) wrapperDiv.current.tabIndex = 1;
|
22
|
+
window.addEventListener("focusin", focusIn);
|
23
|
+
// Remove event listener on cleanup
|
24
|
+
return () => window.removeEventListener("focusin", focusIn);
|
25
|
+
}
|
26
|
+
}, [wrapperDiv.current]);
|
27
|
+
return wrapperDiv;
|
28
|
+
}
|
29
|
+
export function useWindowSize() {
|
30
|
+
// Initialize state with undefined width/height so server and client renders match
|
31
|
+
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
|
32
|
+
const [windowSize, setWindowSize] = useState<{
|
33
|
+
width: number,
|
34
|
+
height: number
|
35
|
+
}>({
|
36
|
+
width: undefined,
|
37
|
+
height: undefined
|
38
|
+
});
|
39
|
+
useEffect(() => {
|
40
|
+
// Handler to call on window resize
|
41
|
+
function handleResize() {
|
42
|
+
|
43
|
+
// Set window width/height to state
|
44
|
+
setWindowSize({
|
45
|
+
width: window.innerWidth,
|
46
|
+
height: window.innerHeight
|
47
|
+
});
|
48
|
+
}
|
49
|
+
// Add event listener
|
50
|
+
window.addEventListener("resize", handleResize);
|
51
|
+
// Call handler right away so state gets updated with initial window size
|
52
|
+
handleResize();
|
53
|
+
// Remove event listener on cleanup
|
54
|
+
return () => window.removeEventListener("resize", handleResize);
|
55
|
+
}, useEffectOnlyOnMount);
|
56
|
+
return windowSize;
|
57
|
+
}
|
58
|
+
export function useElementSize(elm: HTMLElement) {
|
59
|
+
// Initialize state with undefined width/height so server and client renders match
|
60
|
+
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
|
61
|
+
const [elmSize, setELmSize] = useState<{
|
62
|
+
width: number,
|
63
|
+
height: number
|
64
|
+
}>({
|
65
|
+
width: undefined,
|
66
|
+
height: undefined
|
67
|
+
});
|
68
|
+
useEffect(() => {
|
69
|
+
if (elm) {
|
70
|
+
// Handler to call on elm resize
|
71
|
+
function handleResize() {
|
72
|
+
// Set elm width/height to state
|
73
|
+
setELmSize({
|
74
|
+
width: (elm instanceof Window) ? elm.innerWidth : elm.clientWidth,
|
75
|
+
height: (elm instanceof Window) ? elm.innerHeight : elm.clientHeight,
|
76
|
+
});
|
77
|
+
}
|
78
|
+
// Add event listener
|
79
|
+
const observer = new ResizeObserver(handleResize);
|
80
|
+
observer.observe(elm);
|
81
|
+
// Call handler right away so state gets updated with initial elm size
|
82
|
+
handleResize();
|
83
|
+
// Remove event listener on cleanup
|
84
|
+
return () => observer.disconnect();
|
85
|
+
}
|
86
|
+
}, [elm]);
|
87
|
+
return elmSize;
|
88
|
+
}
|
89
|
+
export function useIsInPrint() {
|
90
|
+
// Initialize state with media query
|
91
|
+
const [printMode, setPrintMode] = useState<boolean>(window.matchMedia ? window.matchMedia('print').matches : false);
|
92
|
+
useEffect(() => {
|
93
|
+
if (printMode)
|
94
|
+
document.body.classList.add(KnownClassNames.print);
|
95
|
+
else
|
96
|
+
document.body.classList.remove(KnownClassNames.print);
|
97
|
+
}, [printMode]);
|
98
|
+
|
99
|
+
useEffect(() => {
|
100
|
+
const forcePrintOn = () => setPrintMode(true);
|
101
|
+
const forcePrintOff = () => setPrintMode(false);
|
102
|
+
|
103
|
+
function printDebugHelper(e: KeyboardEvent) {
|
104
|
+
if (e.ctrlKey && e.shiftKey && e.altKey) {
|
105
|
+
if (e.key.toLocaleLowerCase() === "q") {
|
106
|
+
forcePrintOff();
|
107
|
+
}
|
108
|
+
else {
|
109
|
+
console.warn('forced print mode - to exit refresh to ctrl+shift+alt+q');
|
110
|
+
forcePrintOn();
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
// Add event listener
|
116
|
+
window.addEventListener("beforeprint", forcePrintOn);
|
117
|
+
window.addEventListener("afterprint", forcePrintOff);
|
118
|
+
if (isDebug())
|
119
|
+
window.addEventListener("keydown", printDebugHelper);
|
120
|
+
// Remove event listener on cleanup
|
121
|
+
return () => {
|
122
|
+
window.removeEventListener("beforeprint", forcePrintOn);
|
123
|
+
window.removeEventListener("afterprint", forcePrintOff);
|
124
|
+
if (isDebug())
|
125
|
+
window.removeEventListener("keydown", printDebugHelper);
|
126
|
+
};
|
127
|
+
}, useEffectOnlyOnMount);
|
128
|
+
return printMode;
|
129
|
+
}
|
130
|
+
|
131
|
+
export function useKeyDown(options: {
|
132
|
+
//default use document
|
133
|
+
elm?: HTMLElement | Document;
|
134
|
+
onEnter?: (e: KeyboardEvent) => void;
|
135
|
+
onEscape?: (e: KeyboardEvent) => void;
|
136
|
+
onKeyDown?: (e: KeyboardEvent) => void;
|
137
|
+
}) {
|
138
|
+
let elm = options.elm || document;
|
139
|
+
|
140
|
+
useEffect(() => {
|
141
|
+
let handler = (e: KeyboardEvent) => {
|
142
|
+
if (e.key === "Enter" && isFunction(options.onEnter)) options.onEnter(e);
|
143
|
+
else if (e.key === "Escape" && isFunction(options.onEscape)) options.onEscape(e);
|
144
|
+
if (isFunction(options.onKeyDown))
|
145
|
+
options.onKeyDown(e);
|
146
|
+
};
|
147
|
+
elm.addEventListener("keydown", handler);
|
148
|
+
return () => elm.removeEventListener("keydown", handler);
|
149
|
+
}, [elm, options.onEnter, options.onEscape, options.onKeyDown]);
|
150
150
|
}
|