@moser-inc/moser-labs-react 6.8.1 → 7.0.0

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.
Files changed (79) hide show
  1. package/README.md +6 -15
  2. package/dist/index.d.ts +1105 -0
  3. package/dist/index.js +1104 -0
  4. package/package.json +38 -32
  5. package/dist/moser-labs-react.css +0 -1
  6. package/dist/moser-labs-react.d.ts +0 -2
  7. package/dist/moser-labs-react.js +0 -21137
  8. package/dist/package.json.d.ts +0 -84
  9. package/dist/src/_dev/App.d.ts +0 -1
  10. package/dist/src/_dev/components/DevDirectoryLink.d.ts +0 -27
  11. package/dist/src/_dev/components/DevLink.d.ts +0 -10
  12. package/dist/src/_dev/layouts/App.layout.d.ts +0 -1
  13. package/dist/src/_dev/lib/directory.d.ts +0 -29
  14. package/dist/src/_dev/lib/router.d.ts +0 -1
  15. package/dist/src/_dev/lib/routerContext.d.ts +0 -1
  16. package/dist/src/_dev/sandbox.d.ts +0 -0
  17. package/dist/src/_dev/utils/createDocsHeader.d.ts +0 -1
  18. package/dist/src/_dev/views/Base.view.d.ts +0 -2
  19. package/dist/src/_dev/views/FAQ.view.d.ts +0 -2
  20. package/dist/src/_dev/views/Inputs.view.d.ts +0 -205
  21. package/dist/src/_dev/views/Presentation.view.d.ts +0 -2
  22. package/dist/src/components/FieldContainer/FieldContainer.d.ts +0 -16
  23. package/dist/src/components/FieldContainer/FieldContainerHint.d.ts +0 -12
  24. package/dist/src/components/FieldContainer/FieldContainerInput.d.ts +0 -8
  25. package/dist/src/components/FieldContainer/FieldContainerLabel.d.ts +0 -9
  26. package/dist/src/components/FieldContainer/FieldContainerMessage.d.ts +0 -9
  27. package/dist/src/components/LabsAuthGate.d.ts +0 -6
  28. package/dist/src/components/LabsButton.d.ts +0 -10
  29. package/dist/src/components/LabsCalendar.d.ts +0 -8
  30. package/dist/src/components/LabsCheckbox.d.ts +0 -9
  31. package/dist/src/components/LabsCount.d.ts +0 -8
  32. package/dist/src/components/LabsDate.d.ts +0 -7
  33. package/dist/src/components/LabsEmpty.d.ts +0 -6
  34. package/dist/src/components/LabsLoader.d.ts +0 -6
  35. package/dist/src/components/LabsLogoutTimer.d.ts +0 -9
  36. package/dist/src/components/LabsMain.d.ts +0 -7
  37. package/dist/src/components/LabsMainDesktopNav.d.ts +0 -9
  38. package/dist/src/components/LabsMainHeaderActions.d.ts +0 -10
  39. package/dist/src/components/LabsMainMobileNav.d.ts +0 -9
  40. package/dist/src/components/LabsMenuNav.d.ts +0 -8
  41. package/dist/src/components/LabsMultiSelect.d.ts +0 -24
  42. package/dist/src/components/LabsSelect.d.ts +0 -21
  43. package/dist/src/components/LabsSelectCascade.d.ts +0 -23
  44. package/dist/src/components/LabsSpeedDialNav.d.ts +0 -8
  45. package/dist/src/components/LabsText.d.ts +0 -7
  46. package/dist/src/components/LabsTextCurrency.d.ts +0 -3
  47. package/dist/src/components/LabsTextSearch.d.ts +0 -3
  48. package/dist/src/components/LabsTextarea.d.ts +0 -7
  49. package/dist/src/components/LabsToggle.d.ts +0 -6
  50. package/dist/src/constants/app.d.ts +0 -1
  51. package/dist/src/hooks/useAnalytics.d.ts +0 -7
  52. package/dist/src/hooks/useAuth.d.ts +0 -1
  53. package/dist/src/hooks/useBreakpoints.d.ts +0 -4
  54. package/dist/src/hooks/useLabs.d.ts +0 -1
  55. package/dist/src/layouts/Base.layout.d.ts +0 -3
  56. package/dist/src/layouts/Centered.layout.d.ts +0 -3
  57. package/dist/src/layouts/Main.layout.d.ts +0 -18
  58. package/dist/src/lib/analytics/analyticsContext.d.ts +0 -9
  59. package/dist/src/lib/analytics/createAnalytics.d.ts +0 -8
  60. package/dist/src/lib/analytics/index.d.ts +0 -1
  61. package/dist/src/lib/auth/authContext.d.ts +0 -20
  62. package/dist/src/lib/auth/authUtils.d.ts +0 -110
  63. package/dist/src/lib/auth/index.d.ts +0 -4
  64. package/dist/src/lib/dayjs.d.ts +0 -2
  65. package/dist/src/lib/head/headContext.d.ts +0 -5
  66. package/dist/src/lib/head/index.d.ts +0 -1
  67. package/dist/src/lib/labs/index.d.ts +0 -1
  68. package/dist/src/lib/labs/labsContext.d.ts +0 -17
  69. package/dist/src/lib/prime/index.d.ts +0 -1
  70. package/dist/src/lib/prime/primeContext.d.ts +0 -5
  71. package/dist/src/main.d.ts +0 -42
  72. package/dist/src/types/DirectoryValue.type.d.ts +0 -6
  73. package/dist/src/types/ReactHookForm.type.d.ts +0 -6
  74. package/dist/src/utils/animations.d.ts +0 -90
  75. package/dist/src/utils/fieldHelpers.d.ts +0 -5
  76. package/dist/src/utils/forwardRefInferGenerics.d.ts +0 -2
  77. package/dist/src/utils/number.d.ts +0 -2
  78. package/dist/src/utils/pluralize.d.ts +0 -1
  79. package/dist/src/utils/reactHookFormHelpers.d.ts +0 -89
package/dist/index.js ADDED
@@ -0,0 +1,1104 @@
1
+ import { Suspense, createContext, forwardRef, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import Keycloak from "keycloak-js";
3
+ import { registerCustomElements } from "@moser-inc/moser-labs-custom-elements";
4
+ import { UnheadProvider, createHead } from "@unhead/react/client";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { clsx } from "clsx";
7
+ import { PrimeReactProvider } from "primereact/api";
8
+ import mixpanelPlugin from "@analytics/mixpanel";
9
+ import analytics from "analytics";
10
+ import { useMediaQuery } from "@react-hookz/web";
11
+ import { useHead, useSeoMeta } from "@unhead/react";
12
+ import { ProgressSpinner } from "primereact/progressspinner";
13
+ import { Button } from "primereact/button";
14
+ import { Calendar } from "primereact/calendar";
15
+ import dayjs from "dayjs";
16
+ import advancedFormat from "dayjs/plugin/advancedFormat";
17
+ import timezone from "dayjs/plugin/timezone";
18
+ import utc from "dayjs/plugin/utc";
19
+ import { Checkbox } from "primereact/checkbox";
20
+ import { AnimatePresence, motion } from "motion/react";
21
+ import { useIdleTimer } from "react-idle-timer";
22
+ import { Menu } from "primereact/menu";
23
+ import { SpeedDial } from "primereact/speeddial";
24
+ import { MultiSelect } from "primereact/multiselect";
25
+ import { Dropdown } from "primereact/dropdown";
26
+ import { CascadeSelect } from "primereact/cascadeselect";
27
+ import { InputText } from "primereact/inputtext";
28
+ import { InputTextarea } from "primereact/inputtextarea";
29
+ import { Panel } from "primereact/panel";
30
+ //#endregion
31
+ //#region src/constants/app.ts
32
+ const VERSION = "7.0.0";
33
+ //#endregion
34
+ //#region src/lib/head/headContext.tsx
35
+ const head = createHead();
36
+ const LabsHeadProvider = ({ children }) => {
37
+ return /* @__PURE__ */ jsx(UnheadProvider, {
38
+ head,
39
+ children
40
+ });
41
+ };
42
+ //#endregion
43
+ //#region src/lib/prime/primeContext.tsx
44
+ const options = {
45
+ unstyled: false,
46
+ ripple: true,
47
+ pt: {
48
+ column: { headerContent: { className: "inline-flex! ws-nowrap" } },
49
+ dialog: { mask: { className: "labs-mask" } },
50
+ tabmenu: { icon: { className: "pi-fw" } },
51
+ tabpanel: { headerAction: { className: "flex gap-2" } },
52
+ tooltip: { root: { className: "display-unset" } },
53
+ speeddial: { mask: { className: "labs-mask fixed inset-0 z-2 pointer-events-none" } }
54
+ },
55
+ ptOptions: {
56
+ classNameMergeFunction: clsx,
57
+ mergeSections: true,
58
+ mergeProps: true
59
+ }
60
+ };
61
+ const LabsPrimeProvider = ({ children }) => {
62
+ return /* @__PURE__ */ jsx(PrimeReactProvider, {
63
+ value: options,
64
+ children
65
+ });
66
+ };
67
+ //#endregion
68
+ //#region src/lib/labs/labsContext.tsx
69
+ const LabsContext = createContext(null);
70
+ const LabsProvider = ({ children, ...rest }) => {
71
+ return /* @__PURE__ */ jsx(LabsContext, {
72
+ value: rest,
73
+ children: /* @__PURE__ */ jsx(LabsPrimeProvider, { children: /* @__PURE__ */ jsx(LabsHeadProvider, { children }) })
74
+ });
75
+ };
76
+ //#endregion
77
+ //#region src/hooks/useLabs.ts
78
+ const useLabs = () => {
79
+ const context = use(LabsContext);
80
+ if (context === null) throw new Error("useLabs must be used within a LabsProvider");
81
+ return context;
82
+ };
83
+ //#endregion
84
+ //#region src/lib/analytics/createAnalytics.ts
85
+ const OPTIONS_DEFAULT = { debug: false };
86
+ const createAnalytics = ({ appName, options: optionsInit = {} }) => {
87
+ const plugins = [];
88
+ const options = {
89
+ ...OPTIONS_DEFAULT,
90
+ ...optionsInit
91
+ };
92
+ if (options?.tokenMixpanel) plugins.push(mixpanelPlugin({
93
+ token: options?.tokenMixpanel,
94
+ options: { debug: options?.debug ?? false }
95
+ }));
96
+ return analytics({
97
+ app: appName,
98
+ debug: options?.debug ?? false,
99
+ plugins
100
+ });
101
+ };
102
+ //#endregion
103
+ //#region src/lib/analytics/analyticsContext.tsx
104
+ const LabsAnalyticsContext = createContext(null);
105
+ const LabsAnalyticsProvider = ({ appName, children, options }) => {
106
+ return /* @__PURE__ */ jsx(LabsAnalyticsContext, {
107
+ value: useMemo(() => {
108
+ return createAnalytics({
109
+ appName,
110
+ options
111
+ });
112
+ }, [appName, options]),
113
+ children
114
+ });
115
+ };
116
+ //#endregion
117
+ //#region src/lib/auth/authContext.tsx
118
+ const LabsAuthContext = createContext(null);
119
+ const LabsAuthProvider = ({ labsApiUri, rolesClientId, children }) => {
120
+ const labs = useLabs();
121
+ const initializedRef = useRef(false);
122
+ const [user, setUser] = useState(null);
123
+ const analytics = use(LabsAnalyticsContext);
124
+ useEffect(() => {
125
+ if (initializedRef.current) return;
126
+ const init = async () => {
127
+ initializedRef.current = true;
128
+ try {
129
+ await auth.init({ onLoad: "login-required" });
130
+ registerCustomElements({
131
+ preset: labs.preset,
132
+ keycloak: auth,
133
+ analytics,
134
+ apiUri: labsApiUri
135
+ });
136
+ setUser(getParsedUserInfo(rolesClientId));
137
+ } catch (error) {
138
+ console.error("Error Authenticating", error);
139
+ }
140
+ };
141
+ init();
142
+ }, [
143
+ analytics,
144
+ labs.preset,
145
+ labsApiUri,
146
+ rolesClientId
147
+ ]);
148
+ const isAuthenticated = useMemo(() => !!user, [user]);
149
+ const hasAllRoles = useCallback((roles) => {
150
+ if (!roles?.length) return true;
151
+ return (Array.isArray(roles) ? roles : [roles]).every((role) => {
152
+ return user?.roles?.includes(role) ?? false;
153
+ });
154
+ }, [user]);
155
+ const hasRole = useCallback((roles) => {
156
+ if (!roles?.length) return true;
157
+ return (Array.isArray(roles) ? roles : [roles]).some((role) => {
158
+ return user?.roles?.includes(role) ?? false;
159
+ });
160
+ }, [user]);
161
+ return /* @__PURE__ */ jsx(LabsAuthContext, {
162
+ value: useMemo(() => ({
163
+ hasAllRoles,
164
+ hasRole,
165
+ isAuthenticated,
166
+ isLoading: !isAuthenticated,
167
+ keycloak: auth,
168
+ logout: auth.logout,
169
+ refreshToken,
170
+ user
171
+ }), [
172
+ hasAllRoles,
173
+ hasRole,
174
+ isAuthenticated,
175
+ user
176
+ ]),
177
+ children
178
+ });
179
+ };
180
+ //#endregion
181
+ //#region src/lib/auth/authUtils.ts
182
+ const getParsedUserInfo = (rolesClientId) => {
183
+ const { tokenParsed, clientId } = auth;
184
+ if (!tokenParsed || !clientId) return null;
185
+ const { sub: id, user_id: userId, name, given_name: firstName, family_name: lastName, email, job_title: jobTitle } = tokenParsed;
186
+ if (!id) return null;
187
+ const _clientId = rolesClientId ?? clientId;
188
+ return {
189
+ id,
190
+ userId,
191
+ name,
192
+ firstName,
193
+ lastName,
194
+ email,
195
+ jobTitle,
196
+ roles: tokenParsed.resource_access?.[_clientId]?.roles ?? []
197
+ };
198
+ };
199
+ const refreshToken = async () => {
200
+ return auth.updateToken(60);
201
+ };
202
+ const withAuthHeader = (headers) => {
203
+ const { token } = auth;
204
+ if (!token) return headers;
205
+ return {
206
+ ...headers,
207
+ authorization: `Bearer ${token}`
208
+ };
209
+ };
210
+ //#endregion
211
+ //#region src/lib/auth/index.ts
212
+ const auth = new Keycloak("/keycloak.json");
213
+ //#endregion
214
+ //#region src/hooks/useAuth.ts
215
+ const useAuth = () => {
216
+ const context = use(LabsAuthContext);
217
+ if (context === null) throw new Error("useAuth must be used within an LabsAuthProvider");
218
+ return context;
219
+ };
220
+ //#endregion
221
+ //#region src/layouts/Base.layout.tsx
222
+ const LayoutBase = ({ className, children, ...rest }) => {
223
+ const isDark = useMediaQuery("(prefers-color-scheme: dark)");
224
+ const { appName, favicons } = useLabs();
225
+ useHead({ link: [{
226
+ key: "icon",
227
+ rel: "icon",
228
+ href: useMemo(() => {
229
+ return isDark ? favicons.dark : favicons.light;
230
+ }, [favicons, isDark]),
231
+ sizes: "any",
232
+ type: "image/svg+xml"
233
+ }].filter((entry) => entry !== void 0) });
234
+ useSeoMeta({ titleTemplate: (title) => title ? `${title} - ${appName}` : appName });
235
+ return /* @__PURE__ */ jsx("div", {
236
+ id: "app",
237
+ className: clsx(className, "min-h-viewport"),
238
+ ...rest,
239
+ children
240
+ });
241
+ };
242
+ //#endregion
243
+ //#region src/layouts/Centered.layout.tsx
244
+ const LayoutCentered = ({ children, className, ...rest }) => {
245
+ return /* @__PURE__ */ jsx(LayoutBase, {
246
+ ...rest,
247
+ className: clsx(className, "labs-layout items-center justify-center"),
248
+ children
249
+ });
250
+ };
251
+ //#endregion
252
+ //#region src/components/LabsLoader.tsx
253
+ const sizeMap = {
254
+ sm: "40px",
255
+ md: "80px",
256
+ lg: "120px"
257
+ };
258
+ const LabsLoader = ({ label, size = "md", className, ...rest }) => {
259
+ const sizePx = sizeMap[size];
260
+ return /* @__PURE__ */ jsxs("div", {
261
+ className: clsx(className, "flex flex-col items-center"),
262
+ children: [/* @__PURE__ */ jsx(ProgressSpinner, {
263
+ style: {
264
+ width: sizePx,
265
+ height: sizePx
266
+ },
267
+ ...rest
268
+ }), label && /* @__PURE__ */ jsx("div", {
269
+ className: "mt-3",
270
+ children: /* @__PURE__ */ jsx("p", { children: label })
271
+ })]
272
+ });
273
+ };
274
+ //#endregion
275
+ //#region src/components/LabsAuthGate.tsx
276
+ const LabsAuthGate = ({ children, messageLoading = "Loading..." }) => {
277
+ const { isLoading } = useAuth();
278
+ if (isLoading) return /* @__PURE__ */ jsx(LayoutCentered, { children: /* @__PURE__ */ jsx(LabsLoader, { label: messageLoading }) });
279
+ return /* @__PURE__ */ jsx(Fragment, { children });
280
+ };
281
+ //#endregion
282
+ //#region src/components/LabsButton.tsx
283
+ const LabsButton = (props) => {
284
+ const { severity, icon, iconClassName, text = false, outlined = false, rounded = false, iconOnly = false, size, type = "button", label, disabled, className, children, ...rest } = props;
285
+ return /* @__PURE__ */ jsx(Button, {
286
+ icon: useMemo(() => icon ? /* @__PURE__ */ jsx("i", { className: clsx(icon, iconClassName) }) : null, [icon, iconClassName]),
287
+ className: clsx(className, "inline-flex gap-2", {
288
+ [`p-button-${severity}`]: severity,
289
+ "p-button-text": text,
290
+ "p-button-outlined": outlined,
291
+ "p-button-rounded": rounded,
292
+ "p-button-icon-only": iconOnly,
293
+ "p-button-sm": size === "small",
294
+ "p-button-lg": size === "large",
295
+ "p-disabled p-button-disabled": disabled
296
+ }),
297
+ type,
298
+ label,
299
+ disabled,
300
+ ...rest,
301
+ children
302
+ });
303
+ };
304
+ //#endregion
305
+ //#region src/lib/dayjs.ts
306
+ dayjs.extend(utc);
307
+ dayjs.extend(timezone);
308
+ dayjs.extend(advancedFormat);
309
+ var dayjs_default = dayjs;
310
+ //#endregion
311
+ //#region src/utils/forwardRefInferGenerics.ts
312
+ const forwardRefInferGenerics = forwardRef;
313
+ //#endregion
314
+ //#region src/components/LabsCalendar.tsx
315
+ const LabsCalendarBase = (props, ref) => {
316
+ const { value } = props;
317
+ const isDateSelected = useCallback((date) => {
318
+ const selectedDate = Array.isArray(value) ? value.map((date) => dayjs_default(date)) : typeof value === "string" || typeof value === "number" || value instanceof Date ? dayjs_default(value) : null;
319
+ if (!selectedDate) return false;
320
+ if (!Array.isArray(selectedDate)) return selectedDate.isSame(date, "day");
321
+ return selectedDate.some((day) => day.isSame(date, "day"));
322
+ }, [value]);
323
+ return /* @__PURE__ */ jsx(Calendar, {
324
+ ref,
325
+ dateFormat: "mm/dd/yy",
326
+ dateTemplate: useCallback((event) => {
327
+ const { day, month, year, today } = event;
328
+ const date = dayjs_default(new Date(year, month, day));
329
+ const isSelected = isDateSelected(date);
330
+ const ariaLabel = [
331
+ date.format("dddd, MMMM Do, YYYY"),
332
+ isSelected ? "selected" : "not selected",
333
+ today ? "current date" : ""
334
+ ].filter(Boolean).join(", ");
335
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
336
+ "aria-hidden": true,
337
+ children: day
338
+ }), /* @__PURE__ */ jsxs("span", {
339
+ className: "sr-only",
340
+ children: ["Choose ", ariaLabel]
341
+ })] });
342
+ }, [isDateSelected]),
343
+ ...props
344
+ });
345
+ };
346
+ LabsCalendarBase.displayName = "LabsCalendar";
347
+ const LabsCalendar = forwardRefInferGenerics(LabsCalendarBase);
348
+ //#endregion
349
+ //#region src/utils/fieldHelpers.ts
350
+ const toFieldInputProps = (fieldProps) => fieldProps;
351
+ const toFieldSharedProps = (fieldProps) => {
352
+ return { className: clsx("w-full", { "p-invalid": !!fieldProps.message }) };
353
+ };
354
+ //#endregion
355
+ //#region src/components/FieldContainer/FieldContainerHint.tsx
356
+ const FieldContainerHint = ({ id, hintId = `${id}-hint`, hint, solo = false, children = hint, className, ...rest }) => {
357
+ if (!children) return null;
358
+ return /* @__PURE__ */ jsx(motion.span, {
359
+ id: hintId,
360
+ className: clsx(className, "labs-field-hint", { "sr-only": solo }),
361
+ ...rest,
362
+ children
363
+ });
364
+ };
365
+ //#endregion
366
+ //#region src/components/FieldContainer/FieldContainerLabel.tsx
367
+ const FieldContainerLabel = ({ id, labelId = `${id}-label`, label, solo = false, children = label, className, ...rest }) => {
368
+ if (!children) return null;
369
+ return /* @__PURE__ */ jsx(motion.label, {
370
+ id: labelId,
371
+ htmlFor: id,
372
+ className: clsx(className, "labs-field-label", { "sr-only": solo }),
373
+ ...rest,
374
+ children
375
+ });
376
+ };
377
+ //#endregion
378
+ //#region src/utils/animations.ts
379
+ const DEFAULT_TRANSITION_MS = 150;
380
+ const DEFAULT_TRANSITION_SECONDS = 150 / 1e3;
381
+ const transition = { duration: DEFAULT_TRANSITION_SECONDS };
382
+ const fadeAnimation = {
383
+ transition,
384
+ variants: {
385
+ enter: { opacity: 1 },
386
+ exit: { opacity: 0 }
387
+ },
388
+ initial: "exit",
389
+ animate: "enter",
390
+ exit: "exit"
391
+ };
392
+ const slideYFadeAnimation = {
393
+ transition,
394
+ variants: {
395
+ enter: {
396
+ y: "0rem",
397
+ opacity: 1
398
+ },
399
+ exit: {
400
+ y: "-0.25rem",
401
+ opacity: 0
402
+ }
403
+ },
404
+ initial: "exit",
405
+ animate: "enter",
406
+ exit: "exit"
407
+ };
408
+ const slideYFadeReverseAnimation = {
409
+ transition,
410
+ variants: {
411
+ enter: {
412
+ y: "0rem",
413
+ opacity: 1
414
+ },
415
+ exit: {
416
+ y: "0.25rem",
417
+ opacity: 0
418
+ }
419
+ },
420
+ initial: "exit",
421
+ animate: "enter",
422
+ exit: "exit"
423
+ };
424
+ const scaleFadeAnimation = {
425
+ transition,
426
+ variants: {
427
+ enter: {
428
+ scale: 1,
429
+ opacity: 1
430
+ },
431
+ exit: {
432
+ scale: 0,
433
+ opacity: 0
434
+ }
435
+ },
436
+ initial: "exit",
437
+ animate: "enter",
438
+ exit: "exit"
439
+ };
440
+ const scaleFadeSubtleAnimation = {
441
+ transition,
442
+ variants: {
443
+ enter: {
444
+ scale: 1,
445
+ opacity: 1
446
+ },
447
+ exit: {
448
+ scale: .98,
449
+ opacity: 0
450
+ }
451
+ },
452
+ initial: "exit",
453
+ animate: "enter",
454
+ exit: "exit"
455
+ };
456
+ //#endregion
457
+ //#region src/components/FieldContainer/FieldContainerMessage.tsx
458
+ const FieldContainerMessage = ({ id, messageId = `${id}-message`, message, solo = false, children = message, className, ...rest }) => {
459
+ return /* @__PURE__ */ jsx(AnimatePresence, {
460
+ mode: "wait",
461
+ children: children ? /* @__PURE__ */ jsx(motion.span, {
462
+ id: messageId,
463
+ role: "alert",
464
+ "aria-live": "polite",
465
+ className: clsx(className, "labs-field-message", { "sr-only": solo }),
466
+ ...slideYFadeAnimation,
467
+ ...rest,
468
+ children
469
+ }) : null
470
+ });
471
+ };
472
+ //#endregion
473
+ //#region src/components/FieldContainer/FieldContainer.tsx
474
+ const FieldContainer = ({ id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, children, ...rest }) => {
475
+ return /* @__PURE__ */ jsxs(motion.div, {
476
+ id: containerId,
477
+ ...animation,
478
+ ...rest,
479
+ children: [
480
+ /* @__PURE__ */ jsx(FieldContainerLabel, {
481
+ id,
482
+ labelId,
483
+ label,
484
+ className: "text-xs block"
485
+ }),
486
+ children,
487
+ /* @__PURE__ */ jsx(FieldContainerMessage, {
488
+ id,
489
+ messageId,
490
+ message,
491
+ className: "text-xs block"
492
+ }),
493
+ !message && /* @__PURE__ */ jsx(FieldContainerHint, {
494
+ id,
495
+ hintId,
496
+ hint,
497
+ className: "text-xs block"
498
+ })
499
+ ]
500
+ });
501
+ };
502
+ //#endregion
503
+ //#region src/components/LabsCheckbox.tsx
504
+ const LabsCheckbox = (props) => {
505
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, className, checked = false, ...rest } = props;
506
+ return /* @__PURE__ */ jsxs(FieldContainer, {
507
+ id,
508
+ containerId,
509
+ labelId,
510
+ messageId,
511
+ hintId,
512
+ message,
513
+ hint,
514
+ animation,
515
+ className: clsx(className, "flex gap-4 items-center"),
516
+ children: [/* @__PURE__ */ jsx(Checkbox, {
517
+ ...toFieldInputProps(rest),
518
+ ...toFieldSharedProps(props),
519
+ checked,
520
+ inputId: id,
521
+ "aria-describedby": messageId,
522
+ className: "shrink"
523
+ }), /* @__PURE__ */ jsx(FieldContainerLabel, {
524
+ id,
525
+ labelId,
526
+ label,
527
+ className: "font-semibold cursor-pointer"
528
+ })]
529
+ });
530
+ };
531
+ LabsCheckbox.displayName = "LabsCheckbox";
532
+ //#endregion
533
+ //#region src/utils/pluralize.ts
534
+ const pluralize = (count, singular, plural, inclusive = false) => {
535
+ const parsedCount = !isNaN(Number(count)) ? Number(count) : 0;
536
+ if (!inclusive) return parsedCount === 1 ? singular : plural;
537
+ return `${parsedCount} ${parsedCount === 1 ? singular : plural}`;
538
+ };
539
+ //#endregion
540
+ //#region src/components/LabsCount.tsx
541
+ const LabsCount = ({ count, plural, singular, showCount = true }) => {
542
+ return /* @__PURE__ */ jsx("span", { children: pluralize(count, singular, plural, showCount) });
543
+ };
544
+ //#endregion
545
+ //#region src/components/FieldContainer/FieldContainerInput.tsx
546
+ const FieldContainerInput = ({ id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, solo = false, floatLabel = false, prependIcon, appendIcon, className, children, ...rest }) => {
547
+ return /* @__PURE__ */ jsxs(FieldContainer, {
548
+ id,
549
+ containerId,
550
+ labelId,
551
+ messageId,
552
+ hintId,
553
+ className: clsx(className, "flex flex-col gap-1"),
554
+ ...rest,
555
+ children: [
556
+ !floatLabel && /* @__PURE__ */ jsx(FieldContainerLabel, {
557
+ id,
558
+ labelId,
559
+ label,
560
+ solo,
561
+ className: "text-xs"
562
+ }),
563
+ /* @__PURE__ */ jsxs("div", {
564
+ className: clsx("flex w-full", {
565
+ "p-float-label": floatLabel,
566
+ "p-icon-field": !!prependIcon || !!appendIcon,
567
+ "p-icon-field-left": !!prependIcon,
568
+ "p-icon-field-right": !!appendIcon
569
+ }),
570
+ children: [
571
+ prependIcon && /* @__PURE__ */ jsx("i", { className: `${prependIcon} p-input-icon` }),
572
+ appendIcon && /* @__PURE__ */ jsx("i", { className: `${appendIcon} p-input-icon` }),
573
+ children,
574
+ floatLabel && /* @__PURE__ */ jsx(FieldContainerLabel, {
575
+ id,
576
+ labelId,
577
+ label
578
+ })
579
+ ]
580
+ }),
581
+ /* @__PURE__ */ jsx(FieldContainerMessage, {
582
+ id,
583
+ messageId,
584
+ message,
585
+ solo,
586
+ className: "text-xs"
587
+ }),
588
+ !message && /* @__PURE__ */ jsx(FieldContainerHint, {
589
+ id,
590
+ hintId,
591
+ hint,
592
+ solo,
593
+ className: "text-xs"
594
+ })
595
+ ]
596
+ });
597
+ };
598
+ //#endregion
599
+ //#region src/components/LabsDate.tsx
600
+ const LabsDate = (props) => {
601
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, solo, floatLabel, prependIcon, appendIcon, className, ...rest } = props;
602
+ return /* @__PURE__ */ jsx(FieldContainerInput, {
603
+ id,
604
+ containerId,
605
+ labelId,
606
+ messageId,
607
+ hintId,
608
+ label,
609
+ message,
610
+ hint,
611
+ animation,
612
+ solo,
613
+ floatLabel,
614
+ prependIcon,
615
+ appendIcon,
616
+ className,
617
+ children: /* @__PURE__ */ jsx(LabsCalendar, {
618
+ placeholder: solo ? label || rest.placeholder : rest.placeholder,
619
+ ...toFieldInputProps(rest),
620
+ ...toFieldSharedProps(props),
621
+ inputId: id,
622
+ "aria-describedby": messageId
623
+ })
624
+ });
625
+ };
626
+ //#endregion
627
+ //#region src/components/LabsEmpty.tsx
628
+ const LabsEmpty = ({ text, className, icon, children, ...rest }) => {
629
+ return /* @__PURE__ */ jsxs("div", {
630
+ className: clsx(className, "m-block-6 flex flex-col gap-6 items-center"),
631
+ ...rest,
632
+ children: [/* @__PURE__ */ jsx("div", {
633
+ className: "flex max-w-44 w-full items-center justify-center",
634
+ children: children ?? /* @__PURE__ */ jsx("i", { className: `${icon} text-32 text-primary` })
635
+ }), text && /* @__PURE__ */ jsx("span", {
636
+ className: "text-sm text-primary-gradient font-semibold",
637
+ children: text
638
+ })]
639
+ });
640
+ };
641
+ //#endregion
642
+ //#region src/components/LabsLogoutTimer.tsx
643
+ const DELAY_LOGOUT_MILLISECONDS = 1440 * 60 * 1e3;
644
+ const LabsLogoutTimer = ({ children, options, onLogout }) => {
645
+ const delay = options?.delay || DELAY_LOGOUT_MILLISECONDS;
646
+ useIdleTimer({
647
+ onIdle: useCallback(() => {
648
+ onLogout();
649
+ }, [onLogout]),
650
+ timeout: delay
651
+ });
652
+ return children;
653
+ };
654
+ //#endregion
655
+ //#region src/components/LabsMain.tsx
656
+ const LabsMain = ({ item, className, children, ...rest }) => {
657
+ useSeoMeta({ title: item?.TITLE });
658
+ return /* @__PURE__ */ jsx("main", {
659
+ className: clsx(className, "labs-main"),
660
+ ...rest,
661
+ children
662
+ });
663
+ };
664
+ //#endregion
665
+ //#region src/components/LabsMenuNav.tsx
666
+ const LabsMenuNav = ({ items, renderItem, model, role = "navigation", ...rest }) => {
667
+ const modelItems = useMemo(() => items.map(renderItem), [items, renderItem]);
668
+ return /* @__PURE__ */ jsx(Menu, {
669
+ role,
670
+ ...rest,
671
+ model: model ?? modelItems
672
+ });
673
+ };
674
+ //#endregion
675
+ //#region src/components/LabsMainDesktopNav.tsx
676
+ const LabsMainDesktopNav = ({ items, renderItem, className, pt, ...rest }) => {
677
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
678
+ const handleRender = useCallback((item) => renderItem(item, { isMenuOpen }), [renderItem, isMenuOpen]);
679
+ const toggleMenu = useCallback(() => {
680
+ setIsMenuOpen(!isMenuOpen);
681
+ }, [isMenuOpen]);
682
+ return /* @__PURE__ */ jsxs("div", {
683
+ className: clsx(className, "labs-layout-nav", {
684
+ "labs-layout-nav-closed": !isMenuOpen,
685
+ "labs-layout-nav-open": isMenuOpen
686
+ }),
687
+ children: [/* @__PURE__ */ jsx(LabsButton, {
688
+ label: "Toggle Main Navigation",
689
+ icon: "pi-bars",
690
+ iconOnly: true,
691
+ text: true,
692
+ rounded: true,
693
+ className: "labs-layout-nav-button [&>i]:labs-layout-nav-icon",
694
+ onClick: toggleMenu
695
+ }), /* @__PURE__ */ jsx(LabsMenuNav, {
696
+ "aria-label": "Main",
697
+ items,
698
+ className: "labs-layout-nav-menu",
699
+ pt: {
700
+ ...pt,
701
+ menu: { className: "labs-layout-nav-menu-list" }
702
+ },
703
+ renderItem: handleRender,
704
+ ...rest
705
+ })]
706
+ });
707
+ };
708
+ //#endregion
709
+ //#region src/components/LabsSpeedDialNav.tsx
710
+ const LabsSpeedDialNav = ({ items, renderItem, model, role = "navigation", ...rest }) => {
711
+ const modelItems = useMemo(() => items.map(renderItem), [items, renderItem]);
712
+ return /* @__PURE__ */ jsx(SpeedDial, {
713
+ role,
714
+ ...rest,
715
+ model: model ?? modelItems
716
+ });
717
+ };
718
+ //#endregion
719
+ //#region src/components/LabsMainMobileNav.tsx
720
+ const LabsMainMobileNav = ({ items, renderItem, visible, onVisibleChange, className, pt, ...rest }) => {
721
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
722
+ const handleRender = useCallback((item) => renderItem(item, { isMenuOpen }), [renderItem, isMenuOpen]);
723
+ const isVisible = visible ?? isMenuOpen;
724
+ const handleVisibleChange = useCallback((visible) => {
725
+ setIsMenuOpen(visible);
726
+ onVisibleChange?.(visible);
727
+ }, [setIsMenuOpen, onVisibleChange]);
728
+ return /* @__PURE__ */ jsx(LabsSpeedDialNav, {
729
+ "aria-label": "Toggle Main Navigation",
730
+ items,
731
+ radius: 120,
732
+ className: clsx(className, "labs-layout-nav-mobile"),
733
+ showIcon: `labs-layout-nav-icon pi-bars`,
734
+ hideIcon: `labs-layout-nav-icon pi-times`,
735
+ mask: true,
736
+ pt: {
737
+ ...pt,
738
+ menu: { className: "absolute bottom-16" },
739
+ root: { className: "z-3" }
740
+ },
741
+ renderItem: handleRender,
742
+ ...rest,
743
+ visible: isVisible,
744
+ onVisibleChange: handleVisibleChange
745
+ });
746
+ };
747
+ //#endregion
748
+ //#region src/components/LabsMainHeaderActions.tsx
749
+ const LabsMainHeaderActions = () => {
750
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("labs-app-switcher", {}), /* @__PURE__ */ jsx("labs-account", {})] });
751
+ };
752
+ //#endregion
753
+ //#region src/components/LabsMultiSelect.tsx
754
+ const LabsMultiSelect = (props) => {
755
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, solo, floatLabel, prependIcon, appendIcon, className, ...rest } = props;
756
+ return /* @__PURE__ */ jsx(FieldContainerInput, {
757
+ id,
758
+ containerId,
759
+ labelId,
760
+ messageId,
761
+ hintId,
762
+ label,
763
+ message,
764
+ hint,
765
+ animation,
766
+ solo,
767
+ floatLabel,
768
+ prependIcon,
769
+ appendIcon,
770
+ className,
771
+ children: /* @__PURE__ */ jsx(MultiSelect, {
772
+ placeholder: solo ? label || rest.placeholder : rest.placeholder,
773
+ ...toFieldInputProps(rest),
774
+ ...toFieldSharedProps(props),
775
+ inputId: id,
776
+ "aria-describedby": messageId
777
+ })
778
+ });
779
+ };
780
+ //#endregion
781
+ //#region src/components/LabsSelect.tsx
782
+ const LabsSelect = (props) => {
783
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, solo, floatLabel, prependIcon, appendIcon, className, ...rest } = props;
784
+ return /* @__PURE__ */ jsx(FieldContainerInput, {
785
+ id,
786
+ containerId,
787
+ labelId,
788
+ messageId,
789
+ hintId,
790
+ label,
791
+ message,
792
+ hint,
793
+ animation,
794
+ solo,
795
+ floatLabel,
796
+ prependIcon,
797
+ appendIcon,
798
+ className,
799
+ children: /* @__PURE__ */ jsx(Dropdown, {
800
+ placeholder: solo ? label || rest.placeholder : rest.placeholder,
801
+ ...toFieldInputProps(rest),
802
+ ...toFieldSharedProps(props),
803
+ inputId: id,
804
+ "aria-describedby": messageId
805
+ })
806
+ });
807
+ };
808
+ //#endregion
809
+ //#region src/components/LabsSelectCascade.tsx
810
+ const LabsSelectCascade = (props) => {
811
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, solo, floatLabel, prependIcon, appendIcon, className, ...rest } = props;
812
+ return /* @__PURE__ */ jsx(FieldContainerInput, {
813
+ id,
814
+ containerId,
815
+ labelId,
816
+ messageId,
817
+ hintId,
818
+ label,
819
+ message,
820
+ hint,
821
+ animation,
822
+ solo,
823
+ floatLabel,
824
+ prependIcon,
825
+ appendIcon,
826
+ className,
827
+ children: /* @__PURE__ */ jsx(CascadeSelect, {
828
+ placeholder: solo ? label || rest.placeholder : rest.placeholder,
829
+ ...toFieldInputProps(rest),
830
+ ...toFieldSharedProps(props),
831
+ inputId: id,
832
+ "aria-describedby": messageId
833
+ })
834
+ });
835
+ };
836
+ //#endregion
837
+ //#region src/components/LabsText.tsx
838
+ const LabsText = forwardRef((props, ref) => {
839
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, solo, floatLabel, prependIcon, appendIcon, className, ...rest } = props;
840
+ return /* @__PURE__ */ jsx(FieldContainerInput, {
841
+ id,
842
+ containerId,
843
+ labelId,
844
+ messageId,
845
+ hintId,
846
+ label,
847
+ message,
848
+ hint,
849
+ animation,
850
+ solo,
851
+ floatLabel,
852
+ prependIcon,
853
+ appendIcon,
854
+ className,
855
+ children: /* @__PURE__ */ jsx(InputText, {
856
+ placeholder: solo ? label || rest.placeholder : rest.placeholder,
857
+ ...toFieldInputProps(rest),
858
+ ...toFieldSharedProps(props),
859
+ ref,
860
+ id,
861
+ "aria-describedby": messageId
862
+ })
863
+ });
864
+ });
865
+ LabsText.displayName = "LabsText";
866
+ //#endregion
867
+ //#region src/components/LabsTextCurrency.tsx
868
+ const LabsTextCurrency = forwardRef((props, ref) => {
869
+ return /* @__PURE__ */ jsx(LabsText, {
870
+ ref,
871
+ type: "number",
872
+ step: "0.01",
873
+ prependIcon: "pi-dollar",
874
+ ...props
875
+ });
876
+ });
877
+ LabsTextCurrency.displayName = "LabsTextCurrency";
878
+ //#endregion
879
+ //#region src/components/LabsTextSearch.tsx
880
+ const LabsTextSearch = forwardRef((props, ref) => {
881
+ return /* @__PURE__ */ jsx(LabsText, {
882
+ ref,
883
+ type: "search",
884
+ prependIcon: "pi-search",
885
+ ...props
886
+ });
887
+ });
888
+ LabsTextSearch.displayName = "LabsTextSearch";
889
+ //#endregion
890
+ //#region src/components/LabsTextarea.tsx
891
+ const LabsTextarea = forwardRef((props, ref) => {
892
+ const { id, containerId = `${id}-container`, labelId = `${id}-label`, messageId = `${id}-message`, hintId = `${id}-hint`, label, message, hint, animation, solo, floatLabel, prependIcon, appendIcon, className, ...rest } = props;
893
+ return /* @__PURE__ */ jsx(FieldContainerInput, {
894
+ id,
895
+ containerId,
896
+ labelId,
897
+ messageId,
898
+ hintId,
899
+ label,
900
+ message,
901
+ hint,
902
+ animation,
903
+ solo,
904
+ floatLabel,
905
+ prependIcon,
906
+ appendIcon,
907
+ className,
908
+ children: /* @__PURE__ */ jsx(InputTextarea, {
909
+ placeholder: solo ? label || rest.placeholder : rest.placeholder,
910
+ ...toFieldInputProps(rest),
911
+ ...toFieldSharedProps(props),
912
+ id,
913
+ ref,
914
+ "aria-describedby": messageId
915
+ })
916
+ });
917
+ });
918
+ LabsTextarea.displayName = "LabsTextarea";
919
+ //#endregion
920
+ //#region src/components/LabsToggle.tsx
921
+ const LabsToggle = ({ title, children, ...rest }) => {
922
+ const [isCollapsed, setIsCollapsed] = useState(true);
923
+ const handleToggle = useCallback(() => setIsCollapsed(!isCollapsed), [isCollapsed]);
924
+ const template = (options) => {
925
+ return /* @__PURE__ */ jsxs("div", {
926
+ className: clsx(options.className, "gap-4 cursor-pointer items-center"),
927
+ onClick: options.onTogglerClick,
928
+ children: [/* @__PURE__ */ jsx("span", {
929
+ className: clsx(options.titleClassName, "lh-6"),
930
+ children: options.titleElement
931
+ }), /* @__PURE__ */ jsx(LabsButton, {
932
+ label: `Toggle Item`,
933
+ icon: options.collapsed ? "pi-chevron-down" : "pi-chevron-up",
934
+ iconOnly: true,
935
+ className: clsx(options.togglerClassName, "min-w-8"),
936
+ onClick: options.onTogglerClick
937
+ })]
938
+ });
939
+ };
940
+ return /* @__PURE__ */ jsx(Panel, {
941
+ header: title,
942
+ headerTemplate: template,
943
+ toggleable: true,
944
+ collapsed: isCollapsed,
945
+ onToggle: handleToggle,
946
+ ...rest,
947
+ children: /* @__PURE__ */ jsx("div", {
948
+ className: "labs-prose max-w-full",
949
+ children
950
+ })
951
+ });
952
+ };
953
+ //#endregion
954
+ //#region src/hooks/useAnalytics.ts
955
+ const useAnalytics = () => {
956
+ const context = use(LabsAnalyticsContext);
957
+ if (!context) throw new Error("useAnalytics must be used within an AnalyticsProvider");
958
+ return {
959
+ analytics: context,
960
+ identifyUser: useCallback((user) => {
961
+ const currentUserId = user.id;
962
+ if (currentUserId === context.user().userId) return;
963
+ context.identify(currentUserId);
964
+ }, [context]),
965
+ trackEntity: useCallback((eventName, entityName, entityId, payload) => {
966
+ const normalizedEventName = [eventName, entityName?.toLocaleLowerCase()].filter(Boolean).join(" ");
967
+ context.track(normalizedEventName, {
968
+ Entity: entityName,
969
+ ["Entity ID"]: entityId,
970
+ ...payload
971
+ });
972
+ }, [context]),
973
+ trackPageView: useCallback(() => {
974
+ context.page();
975
+ }, [context])
976
+ };
977
+ };
978
+ //#endregion
979
+ //#region src/hooks/useBreakpoints.ts
980
+ const useBreakpoints = () => {
981
+ return {
982
+ isDesktop: useMediaQuery("(min-width: 640px)"),
983
+ isMobile: useMediaQuery("(max-width: 639px)")
984
+ };
985
+ };
986
+ //#endregion
987
+ //#region src/layouts/Main.layout.tsx
988
+ const DefaultLoader = () => /* @__PURE__ */ jsx(LabsLoader, { label: "Working..." });
989
+ const LayoutMain = ({ actions, children, loader = /* @__PURE__ */ jsx(DefaultLoader, {}), name, subtitle, navigation, navigationMobile = navigation, renderNavigation, renderNavigationMobile = renderNavigation, desktopNavProps, mobileNavProps }) => {
990
+ const { isDesktop, isMobile } = useBreakpoints();
991
+ const { appName } = useLabs();
992
+ return /* @__PURE__ */ jsxs(LayoutBase, {
993
+ className: "labs-layout",
994
+ children: [
995
+ isDesktop && /* @__PURE__ */ jsx(LabsMainDesktopNav, {
996
+ ...desktopNavProps,
997
+ items: navigation,
998
+ renderItem: renderNavigation
999
+ }),
1000
+ isMobile && /* @__PURE__ */ jsx(LabsMainMobileNav, {
1001
+ ...mobileNavProps,
1002
+ items: navigationMobile,
1003
+ renderItem: renderNavigationMobile
1004
+ }),
1005
+ /* @__PURE__ */ jsxs("div", {
1006
+ className: "labs-layout-main",
1007
+ children: [/* @__PURE__ */ jsxs("header", {
1008
+ className: "labs-layout-header",
1009
+ children: [/* @__PURE__ */ jsxs("div", {
1010
+ className: "labs-layout-header-content",
1011
+ children: [/* @__PURE__ */ jsx("h1", {
1012
+ className: "labs-layout-header-title",
1013
+ children: typeof name === "function" ? name(appName) : name
1014
+ }), /* @__PURE__ */ jsx("h2", {
1015
+ className: "labs-layout-header-subtitle",
1016
+ children: typeof subtitle === "function" ? subtitle(appName) : subtitle
1017
+ })]
1018
+ }), /* @__PURE__ */ jsx("div", {
1019
+ className: "labs-layout-header-actions",
1020
+ children: typeof actions === "function" ? actions() : actions
1021
+ })]
1022
+ }), /* @__PURE__ */ jsx("div", {
1023
+ className: "labs-layout-main-content",
1024
+ children: /* @__PURE__ */ jsx(Suspense, {
1025
+ fallback: /* @__PURE__ */ jsx("div", {
1026
+ className: "labs-main-center",
1027
+ children: loader
1028
+ }),
1029
+ children
1030
+ })
1031
+ })]
1032
+ })
1033
+ ]
1034
+ });
1035
+ };
1036
+ //#endregion
1037
+ //#region src/utils/number.ts
1038
+ const round = (value, precision) => {
1039
+ const factor = Math.pow(10, precision);
1040
+ return Math.round(value * factor) / factor;
1041
+ };
1042
+ const toCurrency = (number) => {
1043
+ const parsedNumber = parseFloat(String(number));
1044
+ if (isNaN(parsedNumber)) return number;
1045
+ return round(isFinite(parsedNumber) ? parsedNumber : 0, 2).toFixed(2);
1046
+ };
1047
+ const toPrecision = (number = 0, precision = 2) => {
1048
+ const parsedNumber = parseFloat(String(number));
1049
+ return round(isFinite(parsedNumber) ? parsedNumber : 0, precision).toFixed(precision);
1050
+ };
1051
+ //#endregion
1052
+ //#region src/utils/reactHookFormHelpers.ts
1053
+ const toFieldContainerProps = (fieldState) => ({ message: fieldState.error?.message });
1054
+ const toLabsCheckboxProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1055
+ ...field,
1056
+ ...toFieldContainerProps(fieldState),
1057
+ inputRef: ref,
1058
+ checked: value,
1059
+ onChange: (event) => field.onChange(event.checked ?? false)
1060
+ });
1061
+ const toLabsDateProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1062
+ ...field,
1063
+ ...toFieldContainerProps(fieldState),
1064
+ inputRef: ref,
1065
+ value,
1066
+ onChange: (event) => field.onChange(event.value)
1067
+ });
1068
+ const toLabsMultiSelectProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1069
+ ...field,
1070
+ ...toFieldContainerProps(fieldState),
1071
+ inputRef: ref,
1072
+ value,
1073
+ onChange: (event) => field.onChange(event.value)
1074
+ });
1075
+ const toLabsSelectProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1076
+ ...field,
1077
+ ...toFieldContainerProps(fieldState),
1078
+ inputRef: ref,
1079
+ value,
1080
+ onChange: (event) => field.onChange(event.value)
1081
+ });
1082
+ const toLabsSelectCascadeProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1083
+ ...field,
1084
+ ...toFieldContainerProps(fieldState),
1085
+ inputRef: ref,
1086
+ value,
1087
+ onChange: (event) => field.onChange(event.value)
1088
+ });
1089
+ const toLabsTextProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1090
+ ...field,
1091
+ ...toFieldContainerProps(fieldState),
1092
+ ref,
1093
+ value
1094
+ });
1095
+ const toLabsTextCurrencyProps = toLabsTextProps;
1096
+ const toLabsTextSearchProps = toLabsTextProps;
1097
+ const toLabsTextareaProps = ({ field: { ref, value, ...field }, fieldState }) => ({
1098
+ ...field,
1099
+ ...toFieldContainerProps(fieldState),
1100
+ ref,
1101
+ value
1102
+ });
1103
+ //#endregion
1104
+ export { DEFAULT_TRANSITION_MS, DEFAULT_TRANSITION_SECONDS, LabsAnalyticsContext, LabsAnalyticsProvider, LabsAuthContext, LabsAuthGate, LabsAuthProvider, LabsButton, LabsCalendar, LabsCalendarBase, LabsCheckbox, LabsContext, LabsCount, LabsDate, LabsEmpty, LabsHeadProvider, LabsLoader, LabsLogoutTimer, LabsMain, LabsMainDesktopNav, LabsMainHeaderActions, LabsMainMobileNav, LabsMenuNav, LabsMultiSelect, LabsPrimeProvider, LabsProvider, LabsSelect, LabsSelectCascade, LabsSpeedDialNav, LabsText, LabsTextCurrency, LabsTextSearch, LabsTextarea, LabsToggle, LayoutBase, LayoutCentered, LayoutMain, VERSION, auth, fadeAnimation, getParsedUserInfo, pluralize, refreshToken, scaleFadeAnimation, scaleFadeSubtleAnimation, slideYFadeAnimation, slideYFadeReverseAnimation, toCurrency, toFieldContainerProps, toLabsCheckboxProps, toLabsDateProps, toLabsMultiSelectProps, toLabsSelectCascadeProps, toLabsSelectProps, toLabsTextCurrencyProps, toLabsTextProps, toLabsTextSearchProps, toLabsTextareaProps, toPrecision, useAnalytics, useAuth, useBreakpoints, useLabs, withAuthHeader };