@kwiz/fluentui 1.0.57 → 1.0.60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. package/.dependency-cruiser.js +399 -0
  2. package/dist/controls/ColorPickerDialog.js +1 -1
  3. package/dist/controls/ColorPickerDialog.js.map +1 -1
  4. package/dist/controls/button.js +1 -1
  5. package/dist/controls/button.js.map +1 -1
  6. package/dist/controls/canvas/DrawPad.js +1 -1
  7. package/dist/controls/canvas/DrawPad.js.map +1 -1
  8. package/dist/controls/date.js +2 -2
  9. package/dist/controls/date.js.map +1 -1
  10. package/dist/controls/diagram-picker.js +2 -2
  11. package/dist/controls/diagram-picker.js.map +1 -1
  12. package/dist/controls/dropdown.js +1 -1
  13. package/dist/controls/dropdown.js.map +1 -1
  14. package/dist/controls/file-upload.js +1 -2
  15. package/dist/controls/file-upload.js.map +1 -1
  16. package/dist/controls/index.d.ts +31 -0
  17. package/dist/controls/index.js +32 -0
  18. package/dist/controls/index.js.map +1 -0
  19. package/dist/controls/input.js +1 -1
  20. package/dist/controls/input.js.map +1 -1
  21. package/dist/controls/kwizoverflow.js +1 -1
  22. package/dist/controls/kwizoverflow.js.map +1 -1
  23. package/dist/controls/menu.js +2 -2
  24. package/dist/controls/menu.js.map +1 -1
  25. package/dist/controls/prompt.js +2 -2
  26. package/dist/controls/prompt.js.map +1 -1
  27. package/dist/controls/search.js +1 -1
  28. package/dist/controls/search.js.map +1 -1
  29. package/dist/controls/section.js +1 -1
  30. package/dist/controls/section.js.map +1 -1
  31. package/dist/controls/vertical-content.js +1 -1
  32. package/dist/controls/vertical-content.js.map +1 -1
  33. package/dist/helpers/block-nav.d.ts +11 -0
  34. package/dist/helpers/block-nav.js +79 -0
  35. package/dist/helpers/block-nav.js.map +1 -0
  36. package/dist/helpers/{context.d.ts → context-const.d.ts} +0 -1
  37. package/dist/helpers/context-const.js +4 -0
  38. package/dist/helpers/context-const.js.map +1 -0
  39. package/dist/helpers/context-export.d.ts +7 -0
  40. package/dist/helpers/context-export.js +25 -0
  41. package/dist/helpers/context-export.js.map +1 -0
  42. package/dist/helpers/context-internal.d.ts +1 -0
  43. package/dist/helpers/{context.js → context-internal.js} +2 -3
  44. package/dist/helpers/context-internal.js.map +1 -0
  45. package/dist/helpers/drag-drop/drag-drop-container.d.ts +1 -2
  46. package/dist/helpers/drag-drop/drag-drop-container.js.map +1 -1
  47. package/dist/helpers/drag-drop/drag-drop-context-internal.d.ts +4 -0
  48. package/dist/helpers/drag-drop/drag-drop-context-internal.js +9 -0
  49. package/dist/helpers/drag-drop/drag-drop-context-internal.js.map +1 -0
  50. package/dist/helpers/drag-drop/drag-drop-context.d.ts +1 -9
  51. package/dist/helpers/drag-drop/drag-drop-context.js +2 -9
  52. package/dist/helpers/drag-drop/drag-drop-context.js.map +1 -1
  53. package/dist/helpers/drag-drop/drag-drop.types.d.ts +19 -0
  54. package/dist/helpers/drag-drop/drag-drop.types.js +2 -0
  55. package/dist/helpers/drag-drop/drag-drop.types.js.map +1 -0
  56. package/dist/helpers/drag-drop/{exports.d.ts → index.d.ts} +2 -4
  57. package/dist/helpers/drag-drop/{exports.js → index.js} +1 -1
  58. package/dist/helpers/drag-drop/index.js.map +1 -0
  59. package/dist/helpers/drag-drop/use-draggable.d.ts +1 -8
  60. package/dist/helpers/drag-drop/use-draggable.js +1 -1
  61. package/dist/helpers/drag-drop/use-draggable.js.map +1 -1
  62. package/dist/helpers/drag-drop/use-droppable.d.ts +2 -9
  63. package/dist/helpers/drag-drop/use-droppable.js +1 -2
  64. package/dist/helpers/drag-drop/use-droppable.js.map +1 -1
  65. package/dist/helpers/hooks-events.d.ts +21 -0
  66. package/dist/helpers/hooks-events.js +146 -0
  67. package/dist/helpers/hooks-events.js.map +1 -0
  68. package/dist/helpers/hooks.d.ts +0 -69
  69. package/dist/helpers/hooks.js +1 -310
  70. package/dist/helpers/hooks.js.map +1 -1
  71. package/dist/helpers/index.d.ts +7 -0
  72. package/dist/helpers/index.js +8 -0
  73. package/dist/helpers/index.js.map +1 -0
  74. package/dist/helpers/use-alerts.d.ts +14 -0
  75. package/dist/helpers/use-alerts.js +65 -0
  76. package/dist/helpers/use-alerts.js.map +1 -0
  77. package/dist/helpers/use-toast.d.ts +18 -0
  78. package/dist/helpers/use-toast.js +17 -0
  79. package/dist/helpers/use-toast.js.map +1 -0
  80. package/dist/index.d.ts +3 -36
  81. package/dist/index.js +3 -35
  82. package/dist/index.js.map +1 -1
  83. package/dist/styles/index.d.ts +1 -0
  84. package/dist/styles/index.js +2 -0
  85. package/dist/styles/index.js.map +1 -0
  86. package/package.json +5 -3
  87. package/src/controls/ColorPickerDialog.tsx +1 -1
  88. package/src/controls/button.tsx +1 -1
  89. package/src/controls/canvas/DrawPad.tsx +1 -1
  90. package/src/controls/date.tsx +2 -2
  91. package/src/controls/diagram-picker.tsx +2 -2
  92. package/src/controls/dropdown.tsx +1 -1
  93. package/src/controls/file-upload.tsx +1 -3
  94. package/src/controls/index.ts +31 -0
  95. package/src/controls/input.tsx +1 -1
  96. package/src/controls/kwizoverflow.tsx +1 -1
  97. package/src/controls/menu.tsx +2 -2
  98. package/src/controls/prompt.tsx +2 -2
  99. package/src/controls/search.tsx +1 -1
  100. package/src/controls/section.tsx +1 -1
  101. package/src/controls/vertical-content.tsx +1 -1
  102. package/src/helpers/block-nav.tsx +89 -0
  103. package/src/helpers/{context.ts → context-const.ts} +1 -13
  104. package/src/helpers/context-export.tsx +31 -0
  105. package/src/helpers/context-internal.ts +14 -0
  106. package/src/helpers/drag-drop/drag-drop-container.tsx +1 -2
  107. package/src/helpers/drag-drop/drag-drop-context-internal.tsx +10 -0
  108. package/src/helpers/drag-drop/drag-drop-context.tsx +5 -15
  109. package/src/helpers/drag-drop/drag-drop.types.ts +21 -0
  110. package/src/helpers/drag-drop/{exports.ts → index.ts} +2 -4
  111. package/src/helpers/drag-drop/use-draggable.ts +2 -10
  112. package/src/helpers/drag-drop/use-droppable.ts +3 -12
  113. package/src/helpers/hooks-events.ts +153 -0
  114. package/src/helpers/hooks.tsx +1 -360
  115. package/src/helpers/index.ts +8 -0
  116. package/src/helpers/use-alerts.tsx +75 -0
  117. package/src/helpers/use-toast.tsx +30 -0
  118. package/src/index.ts +3 -37
  119. package/src/styles/index.ts +1 -0
  120. package/dist/helpers/context.js.map +0 -1
  121. package/dist/helpers/drag-drop/exports.js.map +0 -1
@@ -1,10 +1,6 @@
1
- import { Label, Link, makeStyles, Toast, ToastBody, Toaster, ToastFooter, ToastIntent, ToastTitle, useId, useToastController } from "@fluentui/react-components";
2
- import { IDictionary, isDebug, isFunction, isNotEmptyArray, isNullOrEmptyString, isPrimitiveValue, isString, jsonClone, jsonStringify, LoggerLevel, objectsEqual, wrapFunction } from "@kwiz/common";
1
+ import { isFunction, isNotEmptyArray, isNullOrEmptyString, isPrimitiveValue, jsonClone, jsonStringify, LoggerLevel, objectsEqual, wrapFunction } from "@kwiz/common";
3
2
  import { MutableRefObject, SetStateAction, useCallback, useEffect, useRef, useState } from "react";
4
3
  import { GetLogger } from "../_modules/config";
5
- import { IPrompterProps, Prompter } from "../controls/prompt";
6
- import { KnownClassNames } from "../styles/styles";
7
- import { iKWIZFluentContext, useKWIZFluentContext } from "./context";
8
4
 
9
5
  const logger = GetLogger("helpers/hooks");
10
6
  /** Empty array ensures that effect is only run on mount */
@@ -99,359 +95,4 @@ export function useStateEX<ValueType>(initialValue: ValueType, options?: {
99
95
  }), []);
100
96
 
101
97
  return [value, setValue, currentValue];
102
- }
103
- export function useTrackFocus(props: { onFocus: () => void, onLoseFocus: () => void, ref?: MutableRefObject<HTMLElement> }) {
104
- const wrapperDiv = props.ref || useRef<HTMLDivElement>(null);
105
- useEffect(() => {
106
- function focusIn(e: FocusEvent) {
107
- let elm = e.target as HTMLElement;//document.activeElement;
108
- if (wrapperDiv.current) {
109
- while (elm && elm !== wrapperDiv.current) {
110
- elm = elm.parentElement;
111
- }
112
- } else elm = null;
113
- if (wrapperDiv.current && elm === wrapperDiv.current) props.onFocus();
114
- else props.onLoseFocus();
115
- }
116
-
117
- if (wrapperDiv.current) {
118
- if (wrapperDiv.current) wrapperDiv.current.tabIndex = 1;
119
- window.addEventListener("focusin", focusIn);
120
- // Remove event listener on cleanup
121
- return () => window.removeEventListener("focusin", focusIn);
122
- }
123
- }, [wrapperDiv.current]);
124
- return wrapperDiv;
125
- }
126
- export function useWindowSize() {
127
- // Initialize state with undefined width/height so server and client renders match
128
- // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
129
- const [windowSize, setWindowSize] = useState<{
130
- width: number,
131
- height: number
132
- }>({
133
- width: undefined,
134
- height: undefined
135
- });
136
- useEffect(() => {
137
- // Handler to call on window resize
138
- function handleResize() {
139
-
140
- // Set window width/height to state
141
- setWindowSize({
142
- width: window.innerWidth,
143
- height: window.innerHeight
144
- });
145
- }
146
- // Add event listener
147
- window.addEventListener("resize", handleResize);
148
- // Call handler right away so state gets updated with initial window size
149
- handleResize();
150
- // Remove event listener on cleanup
151
- return () => window.removeEventListener("resize", handleResize);
152
- }, useEffectOnlyOnMount);
153
- return windowSize;
154
- }
155
- export function useElementSize(elm: HTMLElement) {
156
- // Initialize state with undefined width/height so server and client renders match
157
- // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
158
- const [elmSize, setELmSize] = useState<{
159
- width: number,
160
- height: number
161
- }>({
162
- width: undefined,
163
- height: undefined
164
- });
165
- useEffect(() => {
166
- if (elm) {
167
- // Handler to call on elm resize
168
- function handleResize() {
169
- // Set elm width/height to state
170
- setELmSize({
171
- width: (elm instanceof Window) ? elm.innerWidth : elm.clientWidth,
172
- height: (elm instanceof Window) ? elm.innerHeight : elm.clientHeight,
173
- });
174
- }
175
- // Add event listener
176
- const observer = new ResizeObserver(handleResize);
177
- observer.observe(elm);
178
- // Call handler right away so state gets updated with initial elm size
179
- handleResize();
180
- // Remove event listener on cleanup
181
- return () => observer.disconnect();
182
- }
183
- }, [elm]);
184
- return elmSize;
185
- }
186
- export function useIsInPrint() {
187
- // Initialize state with false
188
- const [printMode, setPrintMode] = useState<boolean>(false);
189
- useEffect(() => {
190
- function forcePrint(e: KeyboardEvent) {
191
- if (e.ctrlKey && e.shiftKey && e.altKey) {
192
- if (e.key.toLocaleLowerCase() === "q") {
193
- document.body.classList.remove(KnownClassNames.print);
194
- handlePrint(e, false);
195
- }
196
- else {
197
- console.warn('forced print mode - to exit refresh to ctrl+shift+alt+q');
198
- document.body.classList.add(KnownClassNames.print);
199
- handlePrint(e, true);
200
- }
201
- }
202
- }
203
- // Handler to call on printing
204
- function handlePrint(e?: Event, force?: boolean) {
205
- if (force === true) setPrintMode(true);
206
- else if (window.matchMedia) {
207
- var mediaQueryList = window.matchMedia('print');
208
- if (mediaQueryList.matches) {
209
- setPrintMode(true);
210
- } else {
211
- setPrintMode(false);
212
- }
213
- }
214
- }
215
- // Add event listener
216
- window.addEventListener("print", handlePrint);
217
- if (isDebug())
218
- window.addEventListener("keydown", forcePrint);
219
- // Call handler right away so state gets updated with initial printing state
220
- handlePrint();
221
- // Remove event listener on cleanup
222
- return () => {
223
- window.removeEventListener("print", handlePrint);
224
- if (isDebug())
225
- window.removeEventListener("keydown", forcePrint);
226
- };
227
- }, useEffectOnlyOnMount);
228
- return printMode;
229
- }
230
- export interface iBlockNav {
231
- setMessage: (id: string, message?: string) => void;
232
- onNav: (nav: () => void) => void;
233
- navPrompt?: JSX.Element;
234
-
235
- }
236
- /** set block message if you want to block nav.
237
- * - call setMessage to add a blocker message
238
- * - call onNav when you have internal navigation (open / close popups)
239
- * - render the navPrompt control to your page
240
- * FYI for page unload, most modern browsers won't show your message but a generic one instead. */
241
- export function useBlockNav(): iBlockNav {
242
- const [, setBlockNavMessages, blockNavMessagesRef] = useStateEX<IDictionary<string>>({});
243
- const [_prompt, setPrompt] = useStateEX<IPrompterProps>(null);
244
-
245
- const getMessagesArr = useCallback(() => {
246
- return Object.keys(blockNavMessagesRef.current).map(id => blockNavMessagesRef.current[id]);
247
- }, useEffectOnlyOnMount);
248
-
249
- const getMessages = useCallback(() => {
250
- return getMessagesArr().join();
251
- }, useEffectOnlyOnMount);
252
-
253
- const onNav = useCallback((nav: () => void) => {
254
- let messages = getMessagesArr();
255
- if (isNotEmptyArray(messages)) {
256
- //need to release react to re-render the prompt
257
- window.setTimeout(() => {
258
- //prompt, if ok - clear messages and nav.
259
- setPrompt({
260
- okButtonText: "Leave",
261
- cancelButtonText: "Cancel",
262
- title: "Leave page?",
263
- children: messages.length > 1
264
- ? <ul>
265
- {messages.map((m, i) => <li key={`m${i}`}>{m}</li>)}
266
- </ul>
267
- : <p>{messages[0]}</p>,
268
- onCancel: () => setPrompt(null),
269
- onOK: () => {
270
- setPrompt(null);
271
- setBlockNavMessages({});//clear messages
272
- nav();
273
- }
274
- });
275
- }, 1);
276
- }
277
- else nav();
278
- }, useEffectOnlyOnMount);
279
-
280
-
281
- useEffect(() => {
282
- function handleBeforeUnload(e: BeforeUnloadEvent) {
283
- //todo: use blockMessageRef.current so that we don't have to re-register every time message changes.
284
- //otherwise we would have to add blockMessage as a dependency for this useEffect
285
- const message = getMessages();
286
- if (!isNullOrEmptyString(message)) {
287
- e.preventDefault();
288
- e.returnValue = message;
289
- }
290
- }
291
- // Add event listener
292
- window.addEventListener("beforeunload", handleBeforeUnload);
293
- // Remove event listener on cleanup
294
- return () => window.removeEventListener("beforeunload", handleBeforeUnload);
295
- }, useEffectOnlyOnMount);
296
- return {
297
- setMessage: (id: string, message?: string) => {
298
- let current = jsonClone(blockNavMessagesRef.current);
299
- if (isNullOrEmptyString(message))
300
- delete current[id];
301
- else current[id] = message;
302
- if (!objectsEqual(current, blockNavMessagesRef.current))
303
- setBlockNavMessages(current);
304
- },
305
- // clearMessages: () => {
306
- // setBlockNavMessages({});
307
- // },
308
- // getMessages,
309
- // getMessagesArr,
310
- onNav,
311
- navPrompt: _prompt ? <Prompter {..._prompt} /> : undefined
312
- };
313
- }
314
-
315
- export function useKeyDown(options: {
316
- //default use document
317
- elm?: HTMLElement | Document;
318
- onEnter?: (e: KeyboardEvent) => void;
319
- onEscape?: (e: KeyboardEvent) => void;
320
- onKeyDown?: (e: KeyboardEvent) => void;
321
- }) {
322
- let elm = options.elm || document;
323
-
324
- useEffect(() => {
325
- let handler = (e: KeyboardEvent) => {
326
- if (e.key === "Enter" && isFunction(options.onEnter)) options.onEnter(e);
327
- else if (e.key === "Escape" && isFunction(options.onEscape)) options.onEscape(e);
328
- if (isFunction(options.onKeyDown))
329
- options.onKeyDown(e);
330
- };
331
- elm.addEventListener("keydown", handler);
332
- return () => elm.removeEventListener("keydown", handler);
333
- }, [elm, options.onEnter, options.onEscape, options.onKeyDown]);
334
- }
335
-
336
-
337
- export function useToast() {
338
- const ctx = useKWIZFluentContext();
339
- const toasterId = useId("toaster");
340
- const { dispatchToast } = useToastController(toasterId);
341
- return {
342
- control: <Toaster mountNode={ctx.mountNode} toasterId={toasterId} />,
343
- dispatch: (info: {
344
- title?: string;
345
- body?: string;
346
- subtitle?: string;
347
- titleAction?: { text: string, onClick: () => void },
348
- footerActions?: { text: string, onClick: () => void }[],
349
- intent?: ToastIntent
350
- }) => {
351
- dispatchToast(<Toast>
352
- {info.title && <ToastTitle action={info.titleAction ? <Link onClick={info.titleAction.onClick}>{info.titleAction.text}</Link> : undefined}>{info.title}</ToastTitle>}
353
- {info.body && <ToastBody subtitle={info.subtitle}>{info.body}</ToastBody>}
354
- {isNotEmptyArray(info.footerActions) &&
355
- <ToastFooter>
356
- {info.footerActions.map((a, i) => <Link key={`l${i}`} onClick={a.onClick}>{a.text}</Link>)}
357
- </ToastFooter>
358
- }
359
- </Toast>, { intent: info.intent || "info" });
360
- }
361
- }
362
- }
363
-
364
- export const useContextStyles = makeStyles({
365
- root: {
366
- "& *": {
367
- scrollbarWidth: "thin"
368
- }
369
- },
370
- })
371
- export function useKWIZFluentContextProvider(options: {
372
- root?: React.MutableRefObject<HTMLDivElement>;
373
- ctx?: iKWIZFluentContext;
374
- }) {
375
- const classes = useContextStyles();
376
- let v: iKWIZFluentContext = options && options.ctx || {};
377
- const [kwizFluentContext, setKwizFluentContext] = useState<iKWIZFluentContext>(v);
378
- useEffect(() => {
379
- options.root?.current?.classList.add(...classes.root.split(' '));
380
- // ref only updates in useEffect, not in useMemo or anything else.
381
- // we need to set it into state so it will trigger a ui update
382
- setKwizFluentContext({
383
- ...v,
384
- mountNode: options.root.current
385
- });
386
- }, [options.root]);
387
- return kwizFluentContext;
388
- }
389
-
390
- export interface iAlerts {
391
- promptEX: (info: IPrompterProps) => void;
392
- confirmEX: (message: string | JSX.Element, onOK?: () => void, onCancel?: () => void) => Promise<boolean>;
393
- alertEX: (message: string | JSX.Element, onOK?: () => void) => Promise<void>;
394
- alertPrompt?: JSX.Element;
395
- close: () => void;
396
- }
397
- /** set block message if you want to block nav.
398
- * - call setMessage to add a blocker message
399
- * - call onNav when you have internal navigation (open / close popups)
400
- * - render the navPrompt control to your page
401
- * FYI for page unload, most modern browsers won't show your message but a generic one instead. */
402
- export function useAlerts(): iAlerts {
403
- const [_prompt, _setPrompt] = useStateEX<IPrompterProps>(null);
404
-
405
- const promptEX = useCallback((info: IPrompterProps) => {
406
- //need to release react to re-render the prompt
407
- window.setTimeout(() => {
408
- //prompt, if ok - clear messages and nav.
409
- _setPrompt({
410
- ...info,
411
- onCancel: () => {
412
- _setPrompt(null);
413
- if (isFunction(info.onCancel)) info.onCancel();
414
- },
415
- onOK: () => {
416
- _setPrompt(null);
417
- if (isFunction(info.onOK)) info.onOK();
418
- }
419
- });
420
- }, 1);
421
- }, useEffectOnlyOnMount);
422
-
423
- const confirmEX = useCallback((message: string | JSX.Element, onOK?: () => void, onCancel?: () => void) => {
424
- return new Promise<boolean>(resolve => {
425
- promptEX({
426
- children: isString(message) ? <Label>{message}</Label> : message,
427
- onCancel: () => {
428
- if (isFunction(onCancel)) onCancel();
429
- resolve(false);
430
- },
431
- onOK: () => {
432
- if (isFunction(onOK)) onOK();
433
- resolve(true);
434
- }
435
- });
436
- });
437
- }, useEffectOnlyOnMount);
438
-
439
- const alertEX = useCallback((message: string | JSX.Element, onOK: () => void) => {
440
- return new Promise<void>(resolve => {
441
- promptEX({
442
- children: isString(message) ? <Label>{message}</Label> : message,
443
- hideCancel: true,
444
- onOK: () => {
445
- if (isFunction(onOK)) onOK();
446
- resolve();
447
- }
448
- });
449
- });
450
- }, useEffectOnlyOnMount);
451
-
452
- return {
453
- promptEX, confirmEX, alertEX,
454
- alertPrompt: _prompt ? <Prompter {..._prompt} /> : undefined,
455
- close: () => _setPrompt(null)
456
- };
457
98
  }
@@ -0,0 +1,8 @@
1
+ export * from './block-nav';
2
+ export * from './context-export';
3
+ export * from './drag-drop';
4
+ export * from './hooks';
5
+ export * from './hooks-events';
6
+ export * from './use-alerts';
7
+ export * from './use-toast';
8
+
@@ -0,0 +1,75 @@
1
+ import { Label } from "@fluentui/react-components";
2
+ import { isFunction, isString } from "@kwiz/common";
3
+ import { useCallback } from "react";
4
+ import { IPrompterProps, Prompter } from "../controls/prompt";
5
+ import { useEffectOnlyOnMount, useStateEX } from "./hooks";
6
+
7
+ export interface iAlerts {
8
+ promptEX: (info: IPrompterProps) => void;
9
+ confirmEX: (message: string | JSX.Element, onOK?: () => void, onCancel?: () => void) => Promise<boolean>;
10
+ alertEX: (message: string | JSX.Element, onOK?: () => void) => Promise<void>;
11
+ alertPrompt?: JSX.Element;
12
+ close: () => void;
13
+ }
14
+
15
+ /** set block message if you want to block nav.
16
+ * - call setMessage to add a blocker message
17
+ * - call onNav when you have internal navigation (open / close popups)
18
+ * - render the navPrompt control to your page
19
+ * FYI for page unload, most modern browsers won't show your message but a generic one instead. */
20
+ export function useAlerts(): iAlerts {
21
+ const [_prompt, _setPrompt] = useStateEX<IPrompterProps>(null);
22
+
23
+ const promptEX = useCallback((info: IPrompterProps) => {
24
+ //need to release react to re-render the prompt
25
+ window.setTimeout(() => {
26
+ //prompt, if ok - clear messages and nav.
27
+ _setPrompt({
28
+ ...info,
29
+ onCancel: () => {
30
+ _setPrompt(null);
31
+ if (isFunction(info.onCancel)) info.onCancel();
32
+ },
33
+ onOK: () => {
34
+ _setPrompt(null);
35
+ if (isFunction(info.onOK)) info.onOK();
36
+ }
37
+ });
38
+ }, 1);
39
+ }, useEffectOnlyOnMount);
40
+
41
+ const confirmEX = useCallback((message: string | JSX.Element, onOK?: () => void, onCancel?: () => void) => {
42
+ return new Promise<boolean>(resolve => {
43
+ promptEX({
44
+ children: isString(message) ? <Label>{message}</Label> : message,
45
+ onCancel: () => {
46
+ if (isFunction(onCancel)) onCancel();
47
+ resolve(false);
48
+ },
49
+ onOK: () => {
50
+ if (isFunction(onOK)) onOK();
51
+ resolve(true);
52
+ }
53
+ });
54
+ });
55
+ }, useEffectOnlyOnMount);
56
+
57
+ const alertEX = useCallback((message: string | JSX.Element, onOK: () => void) => {
58
+ return new Promise<void>(resolve => {
59
+ promptEX({
60
+ children: isString(message) ? <Label>{message}</Label> : message,
61
+ hideCancel: true,
62
+ onOK: () => {
63
+ if (isFunction(onOK)) onOK();
64
+ resolve();
65
+ }
66
+ });
67
+ });
68
+ }, useEffectOnlyOnMount);
69
+
70
+ return {
71
+ promptEX, confirmEX, alertEX,
72
+ alertPrompt: _prompt ? <Prompter {..._prompt} /> : undefined,
73
+ close: () => _setPrompt(null)
74
+ };
75
+ }
@@ -0,0 +1,30 @@
1
+ import { Link, Toast, ToastBody, Toaster, ToastFooter, ToastIntent, ToastTitle, useId, useToastController } from "@fluentui/react-components";
2
+ import { isNotEmptyArray } from "@kwiz/common";
3
+ import { useKWIZFluentContext } from "./context-internal";
4
+
5
+ export function useToast() {
6
+ const ctx = useKWIZFluentContext();
7
+ const toasterId = useId("toaster");
8
+ const { dispatchToast } = useToastController(toasterId);
9
+ return {
10
+ control: <Toaster mountNode={ctx.mountNode} toasterId={toasterId} />,
11
+ dispatch: (info: {
12
+ title?: string;
13
+ body?: string;
14
+ subtitle?: string;
15
+ titleAction?: { text: string, onClick: () => void },
16
+ footerActions?: { text: string, onClick: () => void }[],
17
+ intent?: ToastIntent
18
+ }) => {
19
+ dispatchToast(<Toast>
20
+ {info.title && <ToastTitle action={info.titleAction ? <Link onClick={info.titleAction.onClick}>{info.titleAction.text}</Link> : undefined}>{info.title}</ToastTitle>}
21
+ {info.body && <ToastBody subtitle={info.subtitle}>{info.body}</ToastBody>}
22
+ {isNotEmptyArray(info.footerActions) &&
23
+ <ToastFooter>
24
+ {info.footerActions.map((a, i) => <Link key={`l${i}`} onClick={a.onClick}>{a.text}</Link>)}
25
+ </ToastFooter>
26
+ }
27
+ </Toast>, { intent: info.intent || "info" });
28
+ }
29
+ }
30
+ }
package/src/index.ts CHANGED
@@ -1,37 +1,3 @@
1
- export * from './controls/accordion';
2
- export * from './controls/button';
3
- export * from './controls/canvas/DrawPad';
4
- export * from './controls/card';
5
- export * from './controls/card-list';
6
- export * from './controls/centered';
7
- export * from './controls/ColorPickerDialog';
8
- export * from './controls/date';
9
- export * from './controls/diagram-picker';
10
- export * from './controls/divider';
11
- export * from './controls/dropdown';
12
- export * from './controls/error-boundary';
13
- export * from './controls/field-editor';
14
- export * from './controls/file-upload';
15
- export * from './controls/horizontal';
16
- export * from './controls/html-editor/editor';
17
- export * from './controls/input';
18
- export * from './controls/kwizoverflow';
19
- export * from './controls/list';
20
- export * from './controls/loading';
21
- export * from './controls/menu';
22
- export * from './controls/please-wait';
23
- export * from './controls/progress-bar';
24
- export * from './controls/prompt';
25
- export * from './controls/qrcode';
26
- export * from './controls/search';
27
- export * from './controls/section';
28
- export * from './controls/svg';
29
- export * from './controls/toolbar';
30
- export * from './controls/vertical';
31
- export * from './controls/vertical-content';
32
- export { KWIZFluentContext, useKWIZFluentContext } from './helpers/context';
33
- export type { iKWIZFluentContext } from './helpers/context';
34
- export * from './helpers/drag-drop/exports';
35
- export * from './helpers/hooks';
36
- export { commonSizes, KnownClassNames } from './styles/styles';
37
-
1
+ export * from './controls';
2
+ export * from './helpers';
3
+ export * from './styles';
@@ -0,0 +1 @@
1
+ export { commonSizes, KnownClassNames } from './styles';
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/helpers/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AA2B1B,gBAAgB;AAChB,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAAqB,IAAI,CAAC,CAAC;AAC/E,kCAAkC;AAClC,MAAM,UAAU,oBAAoB;IAChC,IAAI,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACpD,cAAc;IACd,IAAI,iBAAiB,CAAC,GAAG,CAAC,eAAe,CAAC;QACtC,GAAG,CAAC,eAAe,GAAG,WAAW,CAAC;IACtC,IAAI,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC;QAClC,GAAG,CAAC,WAAW,GAAG,UAAU,CAAC;IACjC,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"exports.js","sourceRoot":"","sources":["../../../src/helpers/drag-drop/exports.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}