@ostack.tech/ui-kform 0.4.1 → 0.6.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 (42) hide show
  1. package/dist/chunks/{en-DlhP9NuN.js → en-DdEhXMHn.js} +6 -2
  2. package/dist/chunks/en-DdEhXMHn.js.map +1 -0
  3. package/dist/locales/en-GB.js +5 -5
  4. package/dist/locales/en-GB.js.map +1 -1
  5. package/dist/locales/en-US.js +5 -5
  6. package/dist/locales/en-US.js.map +1 -1
  7. package/dist/locales/{fr.js → fr-FR.js} +10 -6
  8. package/dist/locales/fr-FR.js.map +1 -0
  9. package/dist/locales/{pt.js → pt-PT.js} +10 -6
  10. package/dist/locales/pt-PT.js.map +1 -0
  11. package/dist/ostack-ui-kform.css +37 -9
  12. package/dist/ostack-ui-kform.css.map +1 -1
  13. package/dist/ostack-ui-kform.js +450 -233
  14. package/dist/ostack-ui-kform.js.map +1 -1
  15. package/dist/types/components/Annexes/Annex.d.ts +2 -0
  16. package/dist/types/components/Annexes/Annexes.d.ts +1 -1
  17. package/dist/types/components/FormApp/FormApp.d.ts +6 -2
  18. package/dist/types/components/FormApp/FormAppContext.d.ts +5 -1
  19. package/dist/types/components/FormApp/index.d.ts +1 -1
  20. package/dist/types/components/LoadAction/LoadAction.d.ts +1 -1
  21. package/dist/types/components/PrintAction/PrintAction.d.ts +41 -0
  22. package/dist/types/components/PrintAction/index.d.ts +1 -0
  23. package/dist/types/components/SaveAction/SaveAction.d.ts +1 -1
  24. package/dist/types/components/SubmitAction/SubmitAction.d.ts +1 -1
  25. package/dist/types/components/TableControl/TableControl.d.ts +1 -1
  26. package/dist/types/components/TableControl/TableControlAddRowTrigger.d.ts +6 -0
  27. package/dist/types/components/TableControl/TableControlColumn.d.ts +3 -1
  28. package/dist/types/components/ValidateAction/ValidateAction.d.ts +1 -1
  29. package/dist/types/index.d.ts +1 -0
  30. package/dist/types/locales/en-GB.d.ts +1 -1
  31. package/dist/types/locales/en-US.d.ts +1 -1
  32. package/dist/types/locales/{fr.d.ts → fr-FR.d.ts} +2 -2
  33. package/dist/types/locales/index.d.ts +4 -4
  34. package/dist/types/locales/{pt.d.ts → pt-PT.d.ts} +2 -2
  35. package/dist/types/providers/LocalizationProvider/LocalizationObject.d.ts +3 -1
  36. package/dist/types/utils/useFormSaver.d.ts +19 -3
  37. package/package.json +3 -2
  38. package/scss/components/Annexes/_Annexes.scss +20 -0
  39. package/scss/components/FormPages/_FormPages.scss +10 -1
  40. package/dist/chunks/en-DlhP9NuN.js.map +0 -1
  41. package/dist/locales/fr.js.map +0 -1
  42. package/dist/locales/pt.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { usePrefix as usePrefix$1, useControllableState, useLatestValues, combineEventHandlers, LocalizationProvider as LocalizationProvider$1, useConstant, useSpacing, useCssVars, NATIVE_CONTROLS, useResponsiveValues, useCombinedRef, cx, useIsInRoot, warnOnce, PrefixProvider, Root, computed, TabContent, ErrorBoundary, DocumentTitle, Spinner, useToastManager, Tabs, useErrorReporter, EMPTY_STORE, Field, Feedback, FeedbackList, FeedbackPopover, useMediaBreakpointUp, DropdownMenu, DropdownMenuTrigger, Button, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuGroup, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuItem, useAlertDialog, DropdownMenuRadioItem, controlStatusToAccent, VisuallyHidden, IconButton, Tab, boolDataAttr, TabList, useIsInTableCell, useDataTableColumnLabel, useOnFieldLabelChange, Checkbox, OptionsGroup, Option, CheckboxGroup, useDateTransformer, DateInput, DateRangeInput, Input, Dialog, Tooltip, DialogTrigger, ControlAddon, Icon, DialogContent, DialogHeader, DialogTitle, DialogBody, Alert, Stack, Popover, PopoverTrigger, PopoverContent, useMeasure, Container, Select, MenuListItem, MenuList, StepContent, Step, StepList, Stepper, CloseButton, useScrollPosition, setBoolDataAttr, Card, CardHeader, CardTitle, CardBody, useIntersectionObserver, useKeyboardShortcut, NumericInput, Link, RadioGroup, Radio, ButtonGroup, AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogBody, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, DataTableCell, DataTableRow, useDataTableApiRef, DataTable, Slot, DataTableContent, DataTablePagination, DataTableRowsPerPage, TextArea, PortalContext } from "@ostack.tech/ui";
2
+ import { usePrefix as usePrefix$1, useControllableState, useLatestValues, combineEventHandlers, LocalizationProvider as LocalizationProvider$1, usePrinting, useConstant, useSpacing, useCssVars, NATIVE_CONTROLS, useResponsiveValues, useCombinedRef, cx, useIsInRoot, warnOnce, usePrintInProgress, PrefixProvider, Root, computed, TabContent, ErrorBoundary, DocumentTitle, Spinner, useToastManager, useStartPrintingTask, Tabs, useErrorReporter, EMPTY_STORE, Field, Feedback, FeedbackList, FeedbackPopover, useMediaBreakpointUp, DropdownMenu, DropdownMenuTrigger, Button, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuGroup, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuItem, useAlertDialog, DropdownMenuRadioItem, controlStatusToAccent, VisuallyHidden, IconButton, Tab, boolDataAttr, TabList, useIsInTableCell, useDataTableColumnLabel, useOnFieldLabelChange, Checkbox, OptionsGroup, Option, CheckboxGroup, useDateTransformer, DateInput, DateRangeInput, usePrintClassNames, Input, Dialog, Tooltip, DialogTrigger, ControlAddon, Icon, DialogContent, DialogHeader, DialogTitle, DialogBody, Alert, Stack, Popover, PopoverTrigger, PopoverContent, useMeasure, Container, Select, MenuListItem, MenuList, StepContent, Step, StepList, Stepper, CloseButton, useScrollPosition, setBoolDataAttr, Card, CardHeader, CardTitle, CardBody, useIntersectionObserver, useKeyboardShortcut, NumericInput, Link, usePrint, usePrinterDocumentTitle, PrinterTrigger, RadioGroup, Radio, ButtonGroup, AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogBody, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, DataTableCell, DataTableRow, useDataTableApiRef, DataTable, Slot, DataTableContent, DataTablePagination, DataTableRowsPerPage, TextArea, PortalContext } from "@ostack.tech/ui";
3
3
  import { AbsolutePath, AbsolutePathFragment, PathMultimap, sliceTable, listableSize, Path, ValidationFailure, nullableSchemaInnerSchema, compareSchemaPaths, PromiseCancellationException, arrayToTable, indexOfTableRowId, isComputedSchema } from "@ostack.tech/kform";
4
4
  import { useResolvedPath, equals, useFormController, useForm, FormContext, CurrentPath, useCurrentPath, useFormManager, useFormattedValue, InvalidPathError, AtPathError, useIssuesTracker, useFormContext, useInput, useListableInput, formatTemporalAsString, useTemporalInput, useFileInput, useController, useNumericInput, formatNumericAsString, useFormatter } from "@ostack.tech/kform-react";
5
5
  import { createContext, useContext, useCallback, useMemo, useRef, useEffect, forwardRef, useState, useImperativeHandle, startTransition, Suspense, useDeferredValue, Children, isValidElement, createElement, memo } from "react";
@@ -8,12 +8,12 @@ import { subscribeWithSelector } from "zustand/middleware";
8
8
  import { useShallow } from "zustand/react/shallow";
9
9
  import { shallow } from "zustand/shallow";
10
10
  import { supported, fileOpen, fileSave } from "browser-fs-access";
11
- import { enGB } from "./locales/en-GB.js";
12
- import { enUS } from "./locales/en-US.js";
13
- import { fr } from "./locales/fr.js";
14
- import { pt } from "./locales/pt.js";
15
- import { faChevronUp, faChevronDown, faTrash, faFileLines, faDownload, faCircleQuestion, faArrowsToDot, faAnglesLeft, faAngleLeft, faAngleRight, faAnglesRight, faCircleCheck, faCircleExclamation, faTriangleExclamation, faFolderOpen, faFloppyDisk, faCaretDown, faArrowRight, faPlus } from "@fortawesome/free-solid-svg-icons";
16
11
  import { addDays, min, max, parseISO, format } from "date-fns";
12
+ import { locale } from "./locales/en-GB.js";
13
+ import { locale as locale2 } from "./locales/en-US.js";
14
+ import { locale as locale3, locale as locale4 } from "./locales/fr-FR.js";
15
+ import { locale as locale5, locale as locale6 } from "./locales/pt-PT.js";
16
+ import { faChevronUp, faChevronDown, faTrash, faFileLines, faDownload, faCircleQuestion, faArrowsToDot, faAnglesLeft, faAngleLeft, faAngleRight, faAnglesRight, faCircleCheck, faCircleExclamation, faTriangleExclamation, faFolderOpen, faPrint, faFloppyDisk, faCaretDown, faArrowRight, faPlus } from "@fortawesome/free-solid-svg-icons";
17
17
  import { faCircleCheck as faCircleCheck$1 } from "@fortawesome/free-regular-svg-icons";
18
18
  const DEFAULT_PREFIX_SUFFIX = "kform-";
19
19
  const defaultPrefixSuffixStore = createStore(() => ({
@@ -80,7 +80,7 @@ function ActivePathProvider({
80
80
  [latest, setActivePath]
81
81
  );
82
82
  return /* @__PURE__ */ jsx(
83
- ActivePathContext,
83
+ ActivePathContext.Provider,
84
84
  {
85
85
  value: useMemo(
86
86
  () => ({
@@ -100,18 +100,18 @@ function LocalizationProvider({
100
100
  onLocaleChange,
101
101
  children
102
102
  }) {
103
- const [locale, setLocale] = useControllableState(
103
+ const [locale7, setLocale] = useControllableState(
104
104
  defaultLocale,
105
105
  controlledLocale
106
106
  );
107
- return locale === void 0 ? children : /* @__PURE__ */ jsx(
107
+ return locale7 === void 0 ? children : /* @__PURE__ */ jsx(
108
108
  LocalizationContext.Provider,
109
109
  {
110
110
  value: {
111
- locale,
111
+ locale: locale7,
112
112
  setLocale: combineEventHandlers(setLocale, onLocaleChange)
113
113
  },
114
- children: /* @__PURE__ */ jsx(LocalizationProvider$1, { locale: locale.baseLocale, children })
114
+ children: /* @__PURE__ */ jsx(LocalizationProvider$1, { locale: locale7.baseLocale, children })
115
115
  }
116
116
  );
117
117
  }
@@ -160,6 +160,7 @@ function useEqualityFn(selector, equalityFn = Object.is) {
160
160
  }
161
161
  const FormAppContext = createContext(null);
162
162
  function useCreateFormAppContext({
163
+ formTitle,
163
164
  controller,
164
165
  disabled,
165
166
  readOnly,
@@ -168,7 +169,7 @@ function useCreateFormAppContext({
168
169
  formAppElement,
169
170
  onPathFocus
170
171
  }) {
171
- const listeners = useLatestValues({ onPathFocus });
172
+ const latest = useLatestValues({ printing: usePrinting(), onPathFocus });
172
173
  const store = useConstant(
173
174
  () => createStore()(
174
175
  subscribeWithSelector((set, get) => ({
@@ -188,6 +189,9 @@ function useCreateFormAppContext({
188
189
  deferredLabelRemovalEntryIds: [],
189
190
  actions: {
190
191
  setIssuesPanelPath: (path) => {
192
+ if (latest.printing) {
193
+ return;
194
+ }
191
195
  const {
192
196
  deferredIssueMessageRemovalEntryIds,
193
197
  deferredLabelRemovalEntryIds
@@ -227,6 +231,9 @@ function useCreateFormAppContext({
227
231
  return breadcrumbParts;
228
232
  },
229
233
  focus: (path) => {
234
+ if (latest.printing) {
235
+ return;
236
+ }
230
237
  const { focusedPath } = get();
231
238
  const absolutePath = path instanceof AbsolutePath ? path : new AbsolutePath(path);
232
239
  if (!get().controller.getState().formManager.isValidPath(absolutePath)) {
@@ -243,11 +250,13 @@ function useCreateFormAppContext({
243
250
  focusCounter: focusCounter + 1
244
251
  }));
245
252
  if (focusPathChanged) {
246
- listeners.onPathFocus?.(absolutePath);
253
+ latest.onPathFocus?.(absolutePath);
247
254
  }
248
255
  },
249
256
  resetFocus: () => {
250
- set({ focusedPath: null });
257
+ if (!latest.printing) {
258
+ set({ focusedPath: null });
259
+ }
251
260
  },
252
261
  registerController: (path, controller2) => {
253
262
  if (controller2 == null) {
@@ -263,7 +272,9 @@ function useCreateFormAppContext({
263
272
  },
264
273
  isRegistered: (path) => get().registeredControllers[0].containsPath(path),
265
274
  setLatestInteraction: (path) => {
266
- set({ latestInteraction: path });
275
+ if (!latest.printing) {
276
+ set({ latestInteraction: path });
277
+ }
267
278
  },
268
279
  registerIssueMessages: (basePath, issueMessages, priority = 0) => {
269
280
  if (issueMessages == null) {
@@ -366,6 +377,7 @@ function useCreateFormAppContext({
366
377
  }, [controller, store]);
367
378
  return useMemo(
368
379
  () => ({
380
+ formTitle,
369
381
  disabled,
370
382
  readOnly,
371
383
  issuesDisplayMode,
@@ -377,6 +389,7 @@ function useCreateFormAppContext({
377
389
  disabled,
378
390
  displayIssueCodes,
379
391
  formAppElement,
392
+ formTitle,
380
393
  issuesDisplayMode,
381
394
  readOnly,
382
395
  store
@@ -390,6 +403,9 @@ function useFormAppContext() {
390
403
  }
391
404
  return formAppContext;
392
405
  }
406
+ function useFormTitle() {
407
+ return useFormAppContext().formTitle;
408
+ }
393
409
  function useFormIsDisabled() {
394
410
  return useFormAppContext().disabled;
395
411
  }
@@ -407,23 +423,26 @@ function useFormAppElement() {
407
423
  }
408
424
  function useSetTopBarHeight() {
409
425
  const { store } = useFormAppContext();
426
+ const printing = usePrinting();
410
427
  return useCallback(
411
- (height) => store.setState({ topBarHeight: height ?? 0 }),
412
- [store]
428
+ (height) => !printing && store.setState({ topBarHeight: height ?? 0 }),
429
+ [printing, store]
413
430
  );
414
431
  }
415
432
  function useSetLeftSidebarWidth() {
416
433
  const { store } = useFormAppContext();
434
+ const printing = usePrinting();
417
435
  return useCallback(
418
- (width) => store.setState({ leftSidebarWidth: width ?? 0 }),
419
- [store]
436
+ (width) => !printing && store.setState({ leftSidebarWidth: width ?? 0 }),
437
+ [printing, store]
420
438
  );
421
439
  }
422
440
  function useSetBottomPanelHeight() {
423
441
  const { store } = useFormAppContext();
442
+ const printing = usePrinting();
424
443
  return useCallback(
425
- (height) => store.setState({ bottomPanelHeight: height ?? 0 }),
426
- [store]
444
+ (height) => !printing && store.setState({ bottomPanelHeight: height ?? 0 }),
445
+ [printing, store]
427
446
  );
428
447
  }
429
448
  function useIssuesPanelPath() {
@@ -447,10 +466,12 @@ function useResetFocus() {
447
466
  function useRegisterController(controller) {
448
467
  const store = useFormAppContext().store;
449
468
  const path = controller.usePath();
450
- useEffect(
451
- () => store.getState().actions.registerController(path, controller),
452
- [store, controller, path]
453
- );
469
+ const printing = usePrinting();
470
+ useEffect(() => {
471
+ if (!printing) {
472
+ return store.getState().actions.registerController(path, controller);
473
+ }
474
+ }, [store, controller, path, printing]);
454
475
  }
455
476
  function useIsRegistered(path) {
456
477
  return useStore(
@@ -472,11 +493,12 @@ function useSetLatestInteraction() {
472
493
  }
473
494
  function useRegisterIssueMessages(path, issueMessages, priority) {
474
495
  const store = useFormAppContext().store;
496
+ const printing = usePrinting();
475
497
  useEffect(() => {
476
- if (path != null) {
498
+ if (!printing && path != null) {
477
499
  return store.getState().actions.registerIssueMessages(path, issueMessages, priority);
478
500
  }
479
- }, [path, issueMessages, priority, store]);
501
+ }, [path, issueMessages, priority, store, printing]);
480
502
  }
481
503
  function useRegisteredIssueMessage(path, code) {
482
504
  return useStore(
@@ -486,11 +508,12 @@ function useRegisteredIssueMessage(path, code) {
486
508
  }
487
509
  function useRegisterLabel(path, label, priority = 0) {
488
510
  const store = useFormAppContext().store;
511
+ const printing = usePrinting();
489
512
  useEffect(() => {
490
- if (path != null) {
513
+ if (!printing && path != null) {
491
514
  return store.getState().actions.registerLabel(path, label, priority);
492
515
  }
493
- }, [store, path, label, priority]);
516
+ }, [store, path, label, priority, printing]);
494
517
  }
495
518
  function useActiveIssuesPanelBreadcrumb() {
496
519
  return useStore(
@@ -518,21 +541,26 @@ function useStartIssuesNavigation() {
518
541
  }
519
542
  function useOnPathFocus(cb, { fireImmediately = true } = {}) {
520
543
  const { store } = useFormAppContext();
521
- useEffect(
522
- () => store.subscribe(
523
- ({ focusedPath, focusCounter }) => ({ focusedPath, focusCounter }),
524
- ({ focusedPath }) => focusedPath && cb(focusedPath),
525
- { fireImmediately, equalityFn: shallow }
526
- ),
527
- [cb, fireImmediately, store]
528
- );
544
+ const printing = usePrinting();
545
+ useEffect(() => {
546
+ if (!printing) {
547
+ return store.subscribe(
548
+ ({ focusedPath, focusCounter }) => ({ focusedPath, focusCounter }),
549
+ ({ focusedPath }) => focusedPath && cb(focusedPath),
550
+ { fireImmediately, equalityFn: shallow }
551
+ );
552
+ }
553
+ }, [cb, fireImmediately, printing, store]);
529
554
  }
530
555
  function useSetStartIssuesNavigation(fn) {
531
556
  const { store } = useFormAppContext();
557
+ const printing = usePrinting();
532
558
  useEffect(() => {
533
- store.setState({ startIssuesNavigation: fn });
534
- return () => store.setState({ startIssuesNavigation: void 0 });
535
- }, [fn, store]);
559
+ if (!printing) {
560
+ store.setState({ startIssuesNavigation: fn });
561
+ return () => store.setState({ startIssuesNavigation: void 0 });
562
+ }
563
+ }, [fn, printing, store]);
536
564
  }
537
565
  const FOCUSABLE_ELEMENTS = ["INPUT", "SELECT", "TEXTAREA"];
538
566
  function useControlAutofocus({ usePath, useExists }, enabled = true) {
@@ -741,6 +769,7 @@ const FormApp = forwardRef(function FormApp2({
741
769
  errorBoundaryProps,
742
770
  schema,
743
771
  initialValue,
772
+ formTitle,
744
773
  issuesPanelLabel,
745
774
  disabled = false,
746
775
  readOnly = false,
@@ -813,14 +842,15 @@ const FormApp = forwardRef(function FormApp2({
813
842
  );
814
843
  }
815
844
  const contextLocale = useContext(LocalizationContext)?.locale;
816
- const locale = controlledLocale ?? defaultLocale ?? contextLocale;
817
- if (locale == null) {
845
+ const locale7 = controlledLocale ?? defaultLocale ?? contextLocale;
846
+ if (locale7 == null) {
818
847
  throw new Error(
819
848
  "FormApp: No locale has been provided. Either provide a `defaultLocale`/`locale` property or wrap the component in a `LocalizationProvider`."
820
849
  );
821
850
  }
822
- issuesPanelLabel ??= locale.FormApp.issuesPanelLabel;
823
- confirmUnloadMessage ??= locale.FormApp.confirmUnloadMessage;
851
+ formTitle ??= locale7.FormApp.formTitle;
852
+ issuesPanelLabel ??= locale7.FormApp.issuesPanelLabel ?? formTitle;
853
+ confirmUnloadMessage ??= locale7.FormApp.confirmUnloadMessage;
824
854
  const controller = useForm(schema, {
825
855
  initialValue,
826
856
  externalContexts,
@@ -858,8 +888,10 @@ const FormApp = forwardRef(function FormApp2({
858
888
  }),
859
889
  [controller, formManager]
860
890
  );
861
- const displayDisabled = controller.useSubmitting() || disabled;
891
+ const printInProgress = usePrintInProgress();
892
+ const displayDisabled = controller.useSubmitting() || disabled || printInProgress;
862
893
  const formAppContextValue = useCreateFormAppContext({
894
+ formTitle,
863
895
  disabled: displayDisabled,
864
896
  readOnly,
865
897
  issuesDisplayMode,
@@ -917,7 +949,7 @@ const FormApp = forwardRef(function FormApp2({
917
949
  children: /* @__PURE__ */ jsx(
918
950
  FormAppIssueMessages,
919
951
  {
920
- issueMessages: locale.FormApp.issueMessages,
952
+ issueMessages: locale7.FormApp.issueMessages,
921
953
  priority: -1,
922
954
  children: /* @__PURE__ */ jsxs(FormAppIssueMessages, { issueMessages, children: [
923
955
  /* @__PURE__ */ jsx(FormAppAutoFocus, {}),
@@ -987,6 +1019,7 @@ function useCreateAnnexesContext({
987
1019
  const { activePath, onActivePathChange } = useActivePathContext();
988
1020
  activeAnnex ??= activePath;
989
1021
  const latest = useLatestValues({
1022
+ printing: usePrinting(),
990
1023
  formManager,
991
1024
  onActivePathChange,
992
1025
  onActiveAnnexChange,
@@ -1130,6 +1163,9 @@ function useCreateAnnexesContext({
1130
1163
  return newRepetitiveAnnexStates;
1131
1164
  },
1132
1165
  setActiveAnnex: (path) => {
1166
+ if (latest.printing) {
1167
+ return;
1168
+ }
1133
1169
  const newActiveAnnex = path === null || path instanceof AbsolutePath ? path : new AbsolutePath(path);
1134
1170
  const oldActiveAnnex = get().activeAnnex;
1135
1171
  if (!oldActiveAnnex?.equals(newActiveAnnex)) {
@@ -1144,6 +1180,9 @@ function useCreateAnnexesContext({
1144
1180
  }
1145
1181
  },
1146
1182
  updateActiveAnnex: (oldActiveAnnexIndex) => {
1183
+ if (latest.printing) {
1184
+ return;
1185
+ }
1147
1186
  const tabStates = get().tabStates();
1148
1187
  const nextActiveAnnex = get().nextActiveAnnex;
1149
1188
  if (nextActiveAnnex !== null && tabStates.some((state) => state.path.equals(nextActiveAnnex))) {
@@ -1300,10 +1339,13 @@ const AnnexTabContent = forwardRef(function AnnexTabContent2({
1300
1339
  issueMessages,
1301
1340
  children,
1302
1341
  className,
1342
+ containerProps,
1343
+ tabContentLabelProps,
1303
1344
  errorBoundaryProps,
1304
1345
  ...otherProps
1305
1346
  }, forwardedRef) {
1306
1347
  const prefix = usePrefix();
1348
+ const printing = usePrinting();
1307
1349
  const annexPath = useCurrentPath();
1308
1350
  const documentTitle = useAnnexState(
1309
1351
  annexPath,
@@ -1315,13 +1357,36 @@ const AnnexTabContent = forwardRef(function AnnexTabContent2({
1315
1357
  );
1316
1358
  }
1317
1359
  return /* @__PURE__ */ jsx(
1318
- TabContent,
1360
+ "div",
1319
1361
  {
1320
- className: cx(prefix("annexes__annex"), className),
1321
- value: annexPath.toString(),
1322
- ...otherProps,
1323
- ref: forwardedRef,
1324
- children: /* @__PURE__ */ jsx(ErrorBoundary, { ...errorBoundaryProps, children: /* @__PURE__ */ jsx(DocumentTitle, { title: documentTitle ?? void 0, children: /* @__PURE__ */ jsx(FormAppStatus, { disabled, readOnly, children: /* @__PURE__ */ jsx(FormAppIssueMessages, { issueMessages, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Spinner, { size: "xl", color: "primary" }), children }) }) }) }) })
1362
+ ...containerProps,
1363
+ className: cx(
1364
+ prefix("annexes__annex-container"),
1365
+ containerProps?.className
1366
+ ),
1367
+ children: /* @__PURE__ */ jsx(
1368
+ TabContent,
1369
+ {
1370
+ className: cx(prefix("annexes__annex"), className),
1371
+ value: annexPath.toString(),
1372
+ tabContentLabelProps: {
1373
+ ...tabContentLabelProps,
1374
+ className: cx(
1375
+ prefix("annexes__annex-label"),
1376
+ tabContentLabelProps?.className
1377
+ )
1378
+ },
1379
+ ...otherProps,
1380
+ ref: forwardedRef,
1381
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { ...errorBoundaryProps, children: /* @__PURE__ */ jsx(
1382
+ DocumentTitle,
1383
+ {
1384
+ title: printing ? void 0 : documentTitle ?? void 0,
1385
+ children: /* @__PURE__ */ jsx(FormAppStatus, { disabled, readOnly, children: /* @__PURE__ */ jsx(FormAppIssueMessages, { issueMessages, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Spinner, { size: "xl", color: "primary" }), children }) }) })
1386
+ }
1387
+ ) })
1388
+ }
1389
+ )
1325
1390
  }
1326
1391
  );
1327
1392
  });
@@ -1338,7 +1403,7 @@ function useFormLoader({
1338
1403
  successMessage,
1339
1404
  errorMessage
1340
1405
  } = {}) {
1341
- const [locale] = useLocale();
1406
+ const [locale7] = useLocale();
1342
1407
  const formManager = useFormManager();
1343
1408
  const { _setState } = useFormController();
1344
1409
  const { addToast } = useToastManager();
@@ -1361,10 +1426,10 @@ function useFormLoader({
1361
1426
  throw new Error("No `decode` function was provided.");
1362
1427
  }
1363
1428
  if (successMessage2 === void 0) {
1364
- successMessage2 = locale.LoadAction.successMessage;
1429
+ successMessage2 = locale7.LoadAction.successMessage;
1365
1430
  }
1366
1431
  if (errorMessage2 === void 0) {
1367
- errorMessage2 = locale.LoadAction.errorMessage;
1432
+ errorMessage2 = locale7.LoadAction.errorMessage;
1368
1433
  }
1369
1434
  const validationModeIsAuto = formManager.autoValidationStatus !== "inactive";
1370
1435
  let file = null;
@@ -1439,7 +1504,7 @@ function useFormLoader({
1439
1504
  _setState,
1440
1505
  formManager,
1441
1506
  startIssuesNavigation,
1442
- locale.LoadAction,
1507
+ locale7.LoadAction,
1443
1508
  addToast,
1444
1509
  decode,
1445
1510
  path,
@@ -1469,11 +1534,14 @@ function AnnexRegistrar({
1469
1534
  documentTitle
1470
1535
  }) {
1471
1536
  const store = useAnnexesContext();
1537
+ const printing = usePrinting();
1538
+ const finishPrintingTask = useStartPrintingTask();
1472
1539
  const [isNull = true, controller] = useFormattedValue(
1473
1540
  path.append(AbsolutePathFragment.RecursiveWildcard),
1474
1541
  {
1475
1542
  enabled: !useFormIsLoading(),
1476
- format: useCallback((value) => value === null, [])
1543
+ onInitialized: finishPrintingTask,
1544
+ format: useCallback((value2) => value2 === null, [])
1477
1545
  }
1478
1546
  );
1479
1547
  const isRepetitive = index != null;
@@ -1483,16 +1551,18 @@ function AnnexRegistrar({
1483
1551
  (state) => state.initialized && state.exists
1484
1552
  );
1485
1553
  const dirty = controller.useDirty();
1486
- const deferredValue = useDeferredValue(controller.useValue());
1554
+ const value = controller.useValue();
1555
+ const deferredValue = useDeferredValue(value);
1556
+ const relevantValue = printing ? value : deferredValue;
1487
1557
  const deferredIssuesToDisplay = useDeferredValue(
1488
1558
  controller.useState((state) => state.touched ? state.issues : [], {
1489
1559
  equalityFn: shallow
1490
1560
  })
1491
1561
  );
1492
1562
  const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());
1493
- const actualTitle = isRepetitive ? typeof itemTitle === "function" ? deferredValue === void 0 ? null : itemTitle(deferredValue, index) : itemTitle === void 0 ? title : itemTitle : typeof title === "function" ? deferredValue === void 0 ? null : title(deferredValue) : title;
1494
- const actualSubtitle = typeof subtitle === "function" ? deferredValue === void 0 ? null : subtitle(deferredValue, index) : subtitle;
1495
- const actualDocumentTitle = typeof documentTitle === "function" ? deferredValue === void 0 ? null : documentTitle(deferredValue, index) : documentTitle === void 0 ? (actualTitle === null || typeof actualTitle === "string") && (actualSubtitle == null || typeof actualSubtitle === "string") ? [actualTitle, actualSubtitle].filter((s) => s).join(" — ") : void 0 : documentTitle;
1563
+ const actualTitle = isRepetitive ? typeof itemTitle === "function" ? relevantValue === void 0 ? null : itemTitle(relevantValue, index) : itemTitle === void 0 ? title : itemTitle : typeof title === "function" ? relevantValue === void 0 ? null : title(relevantValue) : title;
1564
+ const actualSubtitle = typeof subtitle === "function" ? relevantValue === void 0 ? null : subtitle(relevantValue, index) : subtitle;
1565
+ const actualDocumentTitle = typeof documentTitle === "function" ? relevantValue === void 0 ? null : documentTitle(relevantValue, index) : documentTitle === void 0 ? (actualTitle === null || typeof actualTitle === "string") && (actualSubtitle == null || typeof actualSubtitle === "string") ? [actualTitle, actualSubtitle].filter((s) => s).join(" — ") : void 0 : documentTitle;
1496
1566
  useEffect(() => {
1497
1567
  if (exists) {
1498
1568
  const { registerAnnexState } = store.getState().actions;
@@ -1546,8 +1616,10 @@ function RepetitiveAnnexRegistrar({
1546
1616
  ...annexProps
1547
1617
  }) {
1548
1618
  const store = useAnnexesContext();
1619
+ const finishPrintingTask = useStartPrintingTask();
1549
1620
  const [rowIds, controller] = useFormattedValue(path.parent(), {
1550
1621
  enabled: !useFormIsLoading(),
1622
+ onInitialized: finishPrintingTask,
1551
1623
  format: useCallback(
1552
1624
  (value) => value == null ? [] : sliceTable(value).map(([id]) => id),
1553
1625
  []
@@ -1700,6 +1772,7 @@ const Annexes = forwardRef(
1700
1772
  activationMode: "manual",
1701
1773
  value: activeAnnexString,
1702
1774
  onValueChange: handleValueChange,
1775
+ showAllTabsWhilePrinting: true,
1703
1776
  ...otherProps,
1704
1777
  ref: forwardedRef,
1705
1778
  children
@@ -1828,9 +1901,9 @@ function IssueMessage({
1828
1901
  unknownWarningMessage,
1829
1902
  issueCodeProps
1830
1903
  }) {
1831
- const [locale] = useLocale();
1832
- unknownErrorMessage ??= locale.IssueMessages.unknownErrorMessage;
1833
- unknownWarningMessage ??= locale.IssueMessages.unknownWarningMessage;
1904
+ const [locale7] = useLocale();
1905
+ unknownErrorMessage ??= locale7.IssueMessages.unknownErrorMessage;
1906
+ unknownWarningMessage ??= locale7.IssueMessages.unknownWarningMessage;
1834
1907
  let message = useRegisteredIssueMessage(path, issue.code);
1835
1908
  const unknownIssue = message == null;
1836
1909
  if (unknownIssue) {
@@ -1927,8 +2000,8 @@ const IssuesPopover = forwardRef(function IssuesPopover2({
1927
2000
  label,
1928
2001
  ...otherProps
1929
2002
  }, forwardedRef) {
1930
- const [locale] = useLocale();
1931
- label ??= locale.IssuesPopover.label;
2003
+ const [locale7] = useLocale();
2004
+ label ??= locale7.IssuesPopover.label;
1932
2005
  const absolutePath = useResolvedPath(path);
1933
2006
  const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);
1934
2007
  const isInControlField = useIsInControlField();
@@ -2392,16 +2465,16 @@ const AnnexesManager = forwardRef(function AnnexManager2({
2392
2465
  ...otherProps
2393
2466
  }, forwardedRef) {
2394
2467
  const prefix = usePrefix();
2395
- const [locale] = useLocale();
2396
- ariaLabel ??= locale.AnnexesManager["aria-label"];
2397
- menuButtonText ??= locale.AnnexesManager.menuButtonText;
2398
- addAnnexText ??= locale.AnnexesManager.addAnnexText;
2399
- removeAnnexButtonLabel ??= locale.AnnexesManager.removeAnnexButtonLabel;
2400
- removeAnnexKeyboardHint ??= locale.AnnexesManager.removeAnnexKeyboardHint;
2401
- removeAnnexConfirmDialogTitle ??= locale.AnnexesManager.removeAnnexConfirmDialogTitle;
2402
- removeAnnexConfirmDialogMessage ??= locale.AnnexesManager.removeAnnexConfirmDialogMessage;
2403
- removeAnnexConfirmDialogOkText ??= locale.AnnexesManager.removeAnnexConfirmDialogOkText;
2404
- removeAnnexConfirmDialogCancelText ??= locale.AnnexesManager.removeAnnexConfirmDialogCancelText;
2468
+ const [locale7] = useLocale();
2469
+ ariaLabel ??= locale7.AnnexesManager["aria-label"];
2470
+ menuButtonText ??= locale7.AnnexesManager.menuButtonText;
2471
+ addAnnexText ??= locale7.AnnexesManager.addAnnexText;
2472
+ removeAnnexButtonLabel ??= locale7.AnnexesManager.removeAnnexButtonLabel;
2473
+ removeAnnexKeyboardHint ??= locale7.AnnexesManager.removeAnnexKeyboardHint;
2474
+ removeAnnexConfirmDialogTitle ??= locale7.AnnexesManager.removeAnnexConfirmDialogTitle;
2475
+ removeAnnexConfirmDialogMessage ??= locale7.AnnexesManager.removeAnnexConfirmDialogMessage;
2476
+ removeAnnexConfirmDialogOkText ??= locale7.AnnexesManager.removeAnnexConfirmDialogOkText;
2477
+ removeAnnexConfirmDialogCancelText ??= locale7.AnnexesManager.removeAnnexConfirmDialogCancelText;
2405
2478
  const store = useAnnexesContext();
2406
2479
  const issuesDisplayMode = useIssuesDisplayMode();
2407
2480
  const tablessStates = useStore(
@@ -2541,6 +2614,7 @@ function useRegisterControl({
2541
2614
  preventAutoFocus,
2542
2615
  apiRef
2543
2616
  }) {
2617
+ const printing = usePrinting();
2544
2618
  const { useState: useState2, usePath, useInitialized, useDisplayStatus } = controller;
2545
2619
  const path = usePath();
2546
2620
  const formIsDisabled = useFormIsDisabled();
@@ -2549,13 +2623,20 @@ function useRegisterControl({
2549
2623
  const deferredIsValidating = useDeferredValue(
2550
2624
  useState2((state) => state.validationStatus === "validating")
2551
2625
  );
2552
- const displayLoading = !useInitialized() || deferredIsValidating;
2626
+ const initialized = useInitialized();
2627
+ const displayLoading = !initialized || deferredIsValidating;
2553
2628
  const displayStatusToDisplay = useDeferredValue(useDisplayStatus());
2554
2629
  const issuesToDisplay = useDeferredValue(
2555
2630
  useState2((state) => state.touched ? state.issues : [], {
2556
2631
  equalityFn: shallow
2557
2632
  })
2558
2633
  );
2634
+ const finishPrintingTask = useStartPrintingTask();
2635
+ useEffect(() => {
2636
+ if (initialized) {
2637
+ finishPrintingTask();
2638
+ }
2639
+ }, [finishPrintingTask, initialized]);
2559
2640
  const columnLabel = useDataTableColumnLabel();
2560
2641
  useRegisterLabel(
2561
2642
  path,
@@ -2568,24 +2649,24 @@ function useRegisterControl({
2568
2649
  useImperativeHandle(apiRef, () => controller, [controller]);
2569
2650
  const autofocusRef = useControlAutofocus(
2570
2651
  controller,
2571
- !preventAutoFocus
2652
+ !preventAutoFocus && !printing
2572
2653
  );
2573
2654
  const setLatestInteraction = useSetLatestInteraction();
2574
2655
  const handleFocus = useCallback(
2575
2656
  (event) => {
2576
- if (event.target === event.currentTarget && !event.defaultPrevented) {
2657
+ if (!printing && event.target === event.currentTarget && !event.defaultPrevented) {
2577
2658
  setLatestInteraction(controller.getState().path);
2578
2659
  }
2579
2660
  },
2580
- [controller, setLatestInteraction]
2661
+ [controller, printing, setLatestInteraction]
2581
2662
  );
2582
2663
  return useMemo(
2583
2664
  () => ({
2584
- displayLoading,
2585
- displayDisabled,
2586
- displayReadOnly,
2587
- displayStatusToDisplay,
2588
- issuesToDisplay,
2665
+ displayLoading: printing ? false : displayLoading,
2666
+ displayDisabled: printing ? false : displayDisabled,
2667
+ displayReadOnly: printing ? false : displayReadOnly,
2668
+ displayStatusToDisplay: printing ? void 0 : displayStatusToDisplay,
2669
+ issuesToDisplay: printing ? [] : issuesToDisplay,
2589
2670
  autofocusRef,
2590
2671
  handleFocus
2591
2672
  }),
@@ -2596,7 +2677,8 @@ function useRegisterControl({
2596
2677
  displayReadOnly,
2597
2678
  displayStatusToDisplay,
2598
2679
  handleFocus,
2599
- issuesToDisplay
2680
+ issuesToDisplay,
2681
+ printing
2600
2682
  ]
2601
2683
  );
2602
2684
  }
@@ -3112,9 +3194,9 @@ const DateRangeControl = forwardRef(function DateRangeControl2({
3112
3194
  endAdornment,
3113
3195
  ...otherProps
3114
3196
  }, forwardedRef) {
3115
- const [locale] = useLocale();
3116
- issuesPanelStartLabelSuffix ??= locale.DateRangeControl.issuesPanelStartLabelSuffix;
3117
- issuesPanelEndLabelSuffix ??= locale.DateRangeControl.issuesPanelEndLabelSuffix;
3197
+ const [locale7] = useLocale();
3198
+ issuesPanelStartLabelSuffix ??= locale7.DateRangeControl.issuesPanelStartLabelSuffix;
3199
+ issuesPanelEndLabelSuffix ??= locale7.DateRangeControl.issuesPanelEndLabelSuffix;
3118
3200
  const { format: format2, parse } = useTemporalStringTransformer({
3119
3201
  locale: dateFnsLocale,
3120
3202
  shortFormat,
@@ -3332,10 +3414,11 @@ const FileControl = forwardRef(function FileControl2({
3332
3414
  ...otherProps
3333
3415
  }, forwardedRef) {
3334
3416
  const prefix = usePrefix();
3335
- const [locale] = useLocale();
3336
- viewFileButtonLabel ??= locale.FileControl.viewFileButtonLabel;
3337
- downloadFileButtonLabel ??= locale.FileControl.downloadFileButtonLabel;
3338
- fallbackText ??= locale.FileControl.fallbackText;
3417
+ const [locale7] = useLocale();
3418
+ viewFileButtonLabel ??= locale7.FileControl.viewFileButtonLabel;
3419
+ downloadFileButtonLabel ??= locale7.FileControl.downloadFileButtonLabel;
3420
+ fallbackText ??= locale7.FileControl.fallbackText;
3421
+ const { printHidden } = usePrintClassNames();
3339
3422
  const latestFileList = useRef(null);
3340
3423
  const [file, setFile] = useState(null);
3341
3424
  const controller = useFileInput(
@@ -3449,7 +3532,7 @@ const FileControl = forwardRef(function FileControl2({
3449
3532
  popoverIssues,
3450
3533
  endAdornment,
3451
3534
  fileInteraction === "view" && file && /* @__PURE__ */ jsxs(Dialog, { children: [
3452
- /* @__PURE__ */ jsx(Tooltip, { content: viewFileButtonLabel, children: /* @__PURE__ */ jsx(DialogTrigger, { children: /* @__PURE__ */ jsx(ControlAddon, { asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", children: /* @__PURE__ */ jsx(Icon, { fixedWidth: true, icon: faFileLines }) }) }) }) }),
3535
+ /* @__PURE__ */ jsx(Tooltip, { content: viewFileButtonLabel, children: /* @__PURE__ */ jsx(DialogTrigger, { children: /* @__PURE__ */ jsx(ControlAddon, { asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", className: printHidden, children: /* @__PURE__ */ jsx(Icon, { fixedWidth: true, icon: faFileLines }) }) }) }) }),
3453
3536
  /* @__PURE__ */ jsxs(
3454
3537
  DialogContent,
3455
3538
  {
@@ -3504,7 +3587,15 @@ const FileControl = forwardRef(function FileControl2({
3504
3587
  }
3505
3588
  )
3506
3589
  ] }),
3507
- fileInteraction === "download" && file && /* @__PURE__ */ jsx(Tooltip, { content: downloadFileButtonLabel, children: /* @__PURE__ */ jsx(ControlAddon, { asChild: true, children: /* @__PURE__ */ jsx("a", { href: dataURL, download: file.name, children: /* @__PURE__ */ jsx(Icon, { icon: faDownload }) }) }) })
3590
+ fileInteraction === "download" && file && /* @__PURE__ */ jsx(Tooltip, { content: downloadFileButtonLabel, children: /* @__PURE__ */ jsx(ControlAddon, { asChild: true, children: /* @__PURE__ */ jsx(
3591
+ "a",
3592
+ {
3593
+ className: printHidden,
3594
+ href: dataURL,
3595
+ download: file.name,
3596
+ children: /* @__PURE__ */ jsx(Icon, { icon: faDownload })
3597
+ }
3598
+ ) }) })
3508
3599
  ] }),
3509
3600
  ...otherProps,
3510
3601
  ref: combinedInputRef
@@ -3526,7 +3617,11 @@ function useCreateFormPagesContext({
3526
3617
  const setLatestInteraction = useSetLatestInteraction();
3527
3618
  const { activePath, onActivePathChange } = useActivePathContext();
3528
3619
  activePage ??= activePath;
3529
- const latest = useLatestValues({ onActivePathChange, onActivePageChange });
3620
+ const latest = useLatestValues({
3621
+ printing: usePrinting(),
3622
+ onActivePathChange,
3623
+ onActivePageChange
3624
+ });
3530
3625
  const store = useConstant(
3531
3626
  () => createStore()(
3532
3627
  subscribeWithSelector((set, get) => ({
@@ -3553,6 +3648,9 @@ function useCreateFormPagesContext({
3553
3648
  get().actions.updateActivePage(oldActivePageIndex);
3554
3649
  },
3555
3650
  setActivePage: (path) => {
3651
+ if (latest.printing) {
3652
+ return;
3653
+ }
3556
3654
  const newActivePage = path === null || path instanceof AbsolutePath ? path : new AbsolutePath(path);
3557
3655
  const oldActivePage = get().activePage;
3558
3656
  if (!oldActivePage?.equals(newActivePage)) {
@@ -3567,7 +3665,7 @@ function useCreateFormPagesContext({
3567
3665
  }
3568
3666
  },
3569
3667
  updateActivePage: (oldActivePageIndex) => {
3570
- if (get().activePage !== null && get().pages.some((page) => page.path.equals(get().activePage))) {
3668
+ if (latest.printing || get().activePage !== null && get().pages.some((page) => page.path.equals(get().activePage))) {
3571
3669
  return;
3572
3670
  }
3573
3671
  get().actions.setActivePage(
@@ -3585,6 +3683,9 @@ function useCreateFormPagesContext({
3585
3683
  get().actions.updateActivePage(oldActivePageIndex);
3586
3684
  },
3587
3685
  setPageHeaderHeight: (path, height) => {
3686
+ if (latest.printing) {
3687
+ return;
3688
+ }
3588
3689
  const {
3589
3690
  pageHeaderHeights: [pageHeaderHeights]
3590
3691
  } = get();
@@ -3658,17 +3759,18 @@ const FormPageHeader = forwardRef(function FormPageHeader2({
3658
3759
  ...otherProps
3659
3760
  }, forwardedRef) {
3660
3761
  const prefix = usePrefix();
3762
+ const printing = usePrinting();
3661
3763
  const currentPath = useCurrentPath();
3662
3764
  const issuesDisplayMode = useIssuesDisplayMode();
3663
3765
  const deferredIssuesToDisplay = useFormPageState(
3664
3766
  currentPath,
3665
3767
  useShallow(
3666
- (state) => issuesDisplayMode === "inline" && state?.deferredIssuesToDisplay || []
3768
+ (state) => !printing && issuesDisplayMode === "inline" && state?.deferredIssuesToDisplay || []
3667
3769
  )
3668
3770
  ) ?? [];
3669
3771
  const deferredDisplayStatus = useFormPageState(
3670
3772
  currentPath,
3671
- (state) => state?.deferredDisplayStatus
3773
+ (state) => printing ? void 0 : state?.deferredDisplayStatus
3672
3774
  );
3673
3775
  const code = useFormPageState(currentPath, (state) => state?.code);
3674
3776
  const title = useFormPageState(currentPath, (state) => state?.title);
@@ -3702,7 +3804,7 @@ const FormPageHeader = forwardRef(function FormPageHeader2({
3702
3804
  children: title
3703
3805
  }
3704
3806
  ),
3705
- /* @__PURE__ */ jsxs(
3807
+ !printing && /* @__PURE__ */ jsxs(
3706
3808
  Stack,
3707
3809
  {
3708
3810
  direction: "row",
@@ -3805,8 +3907,9 @@ const FormPage = forwardRef(
3805
3907
  ...otherProps
3806
3908
  }, forwardedRef) {
3807
3909
  const prefix = usePrefix();
3808
- const [locale] = useLocale();
3809
- helperButtonLabel ??= locale.FormPage.helperButtonLabel;
3910
+ const [locale7] = useLocale();
3911
+ helperButtonLabel ??= locale7.FormPage.helperButtonLabel;
3912
+ const printing = usePrinting();
3810
3913
  const store = useFormPagesContext();
3811
3914
  const pagePath = useResolvedPath(path);
3812
3915
  const activePage = useStore(store, (state) => state.activePage);
@@ -3836,60 +3939,66 @@ const FormPage = forwardRef(
3836
3939
  const formAppEl = useFormAppElement();
3837
3940
  const isFirstDisplay = useRef(true);
3838
3941
  useEffect(() => {
3839
- if (shouldDisplay && isFirstDisplay.current) {
3942
+ if (shouldDisplay && !printing && isFirstDisplay.current) {
3840
3943
  formAppEl.scrollIntoView(true);
3841
3944
  isFirstDisplay.current = false;
3842
3945
  return () => {
3843
3946
  isFirstDisplay.current = true;
3844
3947
  };
3845
3948
  }
3846
- }, [formAppEl, shouldDisplay]);
3949
+ }, [formAppEl, printing, shouldDisplay]);
3847
3950
  const combinedHeaderRef = useCombinedRef(setHeaderEl, headerProps?.ref);
3848
- return shouldDisplay ? /* @__PURE__ */ jsx(CurrentPath, { path: pagePath, children: /* @__PURE__ */ jsx(DocumentTitle, { title: documentTitle ?? void 0, children: /* @__PURE__ */ jsx(
3849
- "div",
3951
+ return shouldDisplay || printing ? /* @__PURE__ */ jsx(CurrentPath, { path: pagePath, children: /* @__PURE__ */ jsx(
3952
+ DocumentTitle,
3850
3953
  {
3851
- className: cx(prefix("form-pages__page"), className),
3852
- ...otherProps,
3853
- ref: forwardedRef,
3854
- children: /* @__PURE__ */ jsx(FormAppStatus, { disabled, readOnly, children: /* @__PURE__ */ jsxs(FormAppIssueMessages, { issueMessages, children: [
3855
- /* @__PURE__ */ jsx(
3856
- FormPageHeader,
3857
- {
3858
- helperText,
3859
- helperButtonLabel,
3860
- ownIssueMessages,
3861
- codeProps,
3862
- titleProps,
3863
- headerPopoverContainerProps,
3864
- issuesPopoverProps,
3865
- issueMessagesProps,
3866
- helperButtonProps,
3867
- helperPopoverProps,
3868
- helperPopoverContentProps,
3869
- ...headerProps,
3870
- ref: combinedHeaderRef
3871
- }
3872
- ),
3873
- /* @__PURE__ */ jsx(
3874
- "div",
3875
- {
3876
- ...contentProps,
3877
- className: cx(
3878
- prefix("form-pages__page-content"),
3879
- contentProps?.className
3954
+ title: printing ? void 0 : documentTitle ?? void 0,
3955
+ children: /* @__PURE__ */ jsx(
3956
+ "div",
3957
+ {
3958
+ className: cx(prefix("form-pages__page"), className),
3959
+ ...otherProps,
3960
+ ref: forwardedRef,
3961
+ children: /* @__PURE__ */ jsx(FormAppStatus, { disabled, readOnly, children: /* @__PURE__ */ jsxs(FormAppIssueMessages, { issueMessages, children: [
3962
+ /* @__PURE__ */ jsx(
3963
+ FormPageHeader,
3964
+ {
3965
+ helperText,
3966
+ helperButtonLabel,
3967
+ ownIssueMessages,
3968
+ codeProps,
3969
+ titleProps,
3970
+ headerPopoverContainerProps,
3971
+ issuesPopoverProps,
3972
+ issueMessagesProps,
3973
+ helperButtonProps,
3974
+ helperPopoverProps,
3975
+ helperPopoverContentProps,
3976
+ ...headerProps,
3977
+ ref: combinedHeaderRef
3978
+ }
3880
3979
  ),
3881
- children: /* @__PURE__ */ jsx(Container, { fluid: "md", gutter: 0, ...containerProps, children: /* @__PURE__ */ jsx(ErrorBoundary, { ...errorBoundaryProps, children: /* @__PURE__ */ jsx(
3882
- Suspense,
3980
+ /* @__PURE__ */ jsx(
3981
+ "div",
3883
3982
  {
3884
- fallback: /* @__PURE__ */ jsx(Spinner, { size: "xl", color: "primary" }),
3885
- children
3983
+ ...contentProps,
3984
+ className: cx(
3985
+ prefix("form-pages__page-content"),
3986
+ contentProps?.className
3987
+ ),
3988
+ children: /* @__PURE__ */ jsx(Container, { fluid: "md", gutter: 0, ...containerProps, children: /* @__PURE__ */ jsx(ErrorBoundary, { ...errorBoundaryProps, children: /* @__PURE__ */ jsx(
3989
+ Suspense,
3990
+ {
3991
+ fallback: /* @__PURE__ */ jsx(Spinner, { size: "xl", color: "primary" }),
3992
+ children
3993
+ }
3994
+ ) }) })
3886
3995
  }
3887
- ) }) })
3888
- }
3889
- )
3890
- ] }) })
3996
+ )
3997
+ ] }) })
3998
+ }
3999
+ )
3891
4000
  }
3892
- ) }) }) : null;
4001
+ ) }) : null;
3893
4002
  }
3894
4003
  );
3895
4004
  function FormPageRegistrar({
@@ -3900,23 +4009,27 @@ function FormPageRegistrar({
3900
4009
  issuesPanelLabel
3901
4010
  }) {
3902
4011
  const store = useFormPagesContext();
4012
+ const printing = usePrinting();
4013
+ const finishPrintingTask = useStartPrintingTask();
3903
4014
  const controller = useController(
3904
4015
  path.append(AbsolutePathFragment.RecursiveWildcard),
3905
- { enabled: !useFormIsLoading() }
4016
+ { enabled: !useFormIsLoading(), onInitialized: finishPrintingTask }
3906
4017
  );
3907
4018
  const absolutePath = controller.usePath();
3908
4019
  const exists = controller.useState(
3909
4020
  (state) => state.initialized && state.exists
3910
4021
  );
3911
- const deferredValue = useDeferredValue(controller.useValue());
4022
+ const value = controller.useValue();
4023
+ const deferredValue = useDeferredValue(value);
4024
+ const relevantValue = printing ? value : deferredValue;
3912
4025
  const deferredIssuesToDisplay = useDeferredValue(
3913
4026
  controller.useState((state) => state.touched ? state.issues : [], {
3914
4027
  equalityFn: shallow
3915
4028
  })
3916
4029
  );
3917
4030
  const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());
3918
- const actualTitle = typeof title === "function" ? deferredValue === void 0 ? null : title(deferredValue) : title;
3919
- const actualDocumentTitle = typeof documentTitle === "function" ? deferredValue === void 0 ? null : documentTitle(deferredValue) : documentTitle === void 0 ? actualTitle === null || typeof actualTitle === "string" ? actualTitle : void 0 : documentTitle;
4031
+ const actualTitle = typeof title === "function" ? relevantValue === void 0 ? null : title(relevantValue) : title;
4032
+ const actualDocumentTitle = typeof documentTitle === "function" ? relevantValue === void 0 ? null : documentTitle(relevantValue) : documentTitle === void 0 ? actualTitle === null || typeof actualTitle === "string" ? actualTitle : void 0 : documentTitle;
3920
4033
  useEffect(() => {
3921
4034
  const { registerPageState } = store.getState().actions;
3922
4035
  registerPageState(absolutePath, {
@@ -4254,13 +4367,14 @@ const FormPagesNavigation = forwardRef(function FormPagesNavigation2({
4254
4367
  ...otherProps
4255
4368
  }, forwardedRef) {
4256
4369
  const prefix = usePrefix();
4257
- const [locale] = useLocale();
4258
- ariaLabel ??= locale.FormPagesNavigation["aria-label"];
4370
+ const [locale7] = useLocale();
4371
+ ariaLabel ??= locale7.FormPagesNavigation["aria-label"];
4372
+ const { printHidden } = usePrintClassNames();
4259
4373
  const isLargeScreen = useMediaBreakpointUp("sm");
4260
4374
  return /* @__PURE__ */ jsx(
4261
4375
  "nav",
4262
4376
  {
4263
- className: cx(prefix("form-pages__navigation"), className),
4377
+ className: cx(prefix("form-pages__navigation"), printHidden, className),
4264
4378
  "data-navigation-mode": isLargeScreen ? "sidebar" : "select",
4265
4379
  "aria-label": ariaLabel,
4266
4380
  ...otherProps,
@@ -4289,6 +4403,7 @@ function useCreateFormStepperContext({
4289
4403
  const { activePath, onActivePathChange } = useActivePathContext();
4290
4404
  activeStep ??= activePath;
4291
4405
  const latest = useLatestValues({
4406
+ printing: usePrinting(),
4292
4407
  formManager,
4293
4408
  onActivePathChange,
4294
4409
  onActiveStepChange,
@@ -4323,6 +4438,9 @@ function useCreateFormStepperContext({
4323
4438
  get().actions.updateActiveStep();
4324
4439
  },
4325
4440
  setActiveStep: (step, callListener = true) => {
4441
+ if (latest.printing) {
4442
+ return;
4443
+ }
4326
4444
  const oldActiveStep = get().activeStep;
4327
4445
  if (!oldActiveStep?.path.equals(step?.path) || oldActiveStep?.index !== step?.index) {
4328
4446
  startTransition(() => {
@@ -4341,7 +4459,7 @@ function useCreateFormStepperContext({
4341
4459
  }
4342
4460
  },
4343
4461
  updateActiveStep: () => {
4344
- if (get().activeStep !== null && get().steps.some(
4462
+ if (latest.printing || get().activeStep !== null && get().steps.some(
4345
4463
  (step) => step.path.equals(get().activeStep.path)
4346
4464
  )) {
4347
4465
  return;
@@ -4363,6 +4481,9 @@ function useCreateFormStepperContext({
4363
4481
  get().actions.updateActiveStep();
4364
4482
  },
4365
4483
  goToStep: async (newStepIndex) => {
4484
+ if (latest.printing) {
4485
+ return;
4486
+ }
4366
4487
  const oldActiveStep = get().activeStep;
4367
4488
  const newActiveStep = get().steps[newStepIndex];
4368
4489
  if (oldActiveStep?.path != newActiveStep?.path && (oldActiveStep?.path == null || newActiveStep?.path == null) || oldActiveStep?.path != null && newActiveStep?.path != null && !newActiveStep.path.contains(oldActiveStep.path)) {
@@ -4529,15 +4650,18 @@ function FormStepRegistrar({
4529
4650
  issuesPanelLabel
4530
4651
  }) {
4531
4652
  const store = useFormStepperContext();
4653
+ const printing = usePrinting();
4532
4654
  const controller = useController(path, { enabled: !useFormIsLoading() });
4533
4655
  const absolutePath = controller.usePath();
4534
4656
  const exists = controller.useState(
4535
4657
  (state) => state.initialized && state.exists
4536
4658
  );
4537
- const deferredValue = useDeferredValue(controller.useValue());
4659
+ const value = controller.useValue();
4660
+ const deferredValue = useDeferredValue(value);
4661
+ const relevantValue = printing ? value : deferredValue;
4538
4662
  const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());
4539
- const actualTitle = typeof title === "function" ? deferredValue === void 0 ? null : title(deferredValue) : title;
4540
- const actualDocumentTitle = typeof documentTitle === "function" ? deferredValue === void 0 ? null : documentTitle(deferredValue) : documentTitle === void 0 ? actualTitle === null || typeof actualTitle === "string" ? actualTitle : void 0 : documentTitle;
4663
+ const actualTitle = typeof title === "function" ? relevantValue === void 0 ? null : title(relevantValue) : title;
4664
+ const actualDocumentTitle = typeof documentTitle === "function" ? relevantValue === void 0 ? null : documentTitle(relevantValue) : documentTitle === void 0 ? actualTitle === null || typeof actualTitle === "string" ? actualTitle : void 0 : documentTitle;
4541
4665
  useEffect(() => {
4542
4666
  const { registerStepState } = store.getState().actions;
4543
4667
  registerStepState(absolutePath, {
@@ -5154,22 +5278,23 @@ const IssuesPanel = forwardRef(function ValidationPanel({
5154
5278
  ...otherProps
5155
5279
  }, forwardedRef) {
5156
5280
  const prefix = usePrefix();
5157
- const [locale] = useLocale();
5158
- errorsLabel ??= locale.IssuesPanel.errorsLabel;
5159
- warningsLabel ??= locale.IssuesPanel.warningsLabel;
5160
- focusButtonLabel ??= locale.IssuesPanel.focusButtonLabel;
5161
- previousIssueButtonLabel ??= locale.IssuesPanel.previousIssueButtonLabel;
5162
- nextIssueButtonLabel ??= locale.IssuesPanel.nextIssueButtonLabel;
5163
- firstIssueButtonLabel ??= locale.IssuesPanel.firstIssueButtonLabel;
5164
- lastIssueButtonLabel ??= locale.IssuesPanel.lastIssueButtonLabel;
5165
- paginationLabel ??= locale.IssuesPanel.paginationLabel;
5166
- noIssuesMessage ??= locale.IssuesPanel.noIssuesMessage;
5167
- resolvedTitle ??= locale.IssuesPanel.resolvedTitle;
5168
- resolvedMessage ??= locale.IssuesPanel.resolvedMessage;
5281
+ const printing = usePrinting();
5282
+ const [locale7] = useLocale();
5283
+ errorsLabel ??= locale7.IssuesPanel.errorsLabel;
5284
+ warningsLabel ??= locale7.IssuesPanel.warningsLabel;
5285
+ focusButtonLabel ??= locale7.IssuesPanel.focusButtonLabel;
5286
+ previousIssueButtonLabel ??= locale7.IssuesPanel.previousIssueButtonLabel;
5287
+ nextIssueButtonLabel ??= locale7.IssuesPanel.nextIssueButtonLabel;
5288
+ firstIssueButtonLabel ??= locale7.IssuesPanel.firstIssueButtonLabel;
5289
+ lastIssueButtonLabel ??= locale7.IssuesPanel.lastIssueButtonLabel;
5290
+ paginationLabel ??= locale7.IssuesPanel.paginationLabel;
5291
+ noIssuesMessage ??= locale7.IssuesPanel.noIssuesMessage;
5292
+ resolvedTitle ??= locale7.IssuesPanel.resolvedTitle;
5293
+ resolvedMessage ??= locale7.IssuesPanel.resolvedMessage;
5169
5294
  const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);
5170
5295
  const formIsLoading = useFormIsLoading();
5171
5296
  const issuesTrackerResult = useIssuesTracker(AbsolutePath.MATCH_ALL, {
5172
- enabled: open && !formIsLoading,
5297
+ enabled: open && !formIsLoading && !printing,
5173
5298
  issuesOrderCompareFn
5174
5299
  });
5175
5300
  useReportValidationFailures(issuesTrackerResult.info);
@@ -5332,7 +5457,7 @@ const IssuesPanel = forwardRef(function ValidationPanel({
5332
5457
  setContainerEl,
5333
5458
  containerProps?.ref
5334
5459
  );
5335
- return open && /* @__PURE__ */ jsx(
5460
+ return open && !printing && /* @__PURE__ */ jsx(
5336
5461
  "div",
5337
5462
  {
5338
5463
  ...containerProps,
@@ -5421,6 +5546,7 @@ function LoadAction({
5421
5546
  label,
5422
5547
  keybinds,
5423
5548
  loading,
5549
+ enabledWhenLoading,
5424
5550
  disabled,
5425
5551
  onClick,
5426
5552
  decode,
@@ -5436,9 +5562,9 @@ function LoadAction({
5436
5562
  errorMessage,
5437
5563
  ...otherProps
5438
5564
  }) {
5439
- const [locale] = useLocale();
5440
- label ??= locale.LoadAction.label;
5441
- keybinds ??= locale.LoadAction.keybinds;
5565
+ const [locale7] = useLocale();
5566
+ label ??= locale7.LoadAction.label;
5567
+ keybinds ??= locale7.LoadAction.keybinds;
5442
5568
  const { load } = useFormLoader({
5443
5569
  decode,
5444
5570
  path,
@@ -5452,10 +5578,12 @@ function LoadAction({
5452
5578
  successMessage,
5453
5579
  errorMessage
5454
5580
  });
5455
- const formIsLoading = useFormIsLoading();
5456
5581
  const formIsDisabled = useFormIsDisabled();
5582
+ const formIsLoading = useFormIsLoading();
5583
+ const shouldDisable = disabled || loading && !enabledWhenLoading || formIsDisabled || formIsLoading;
5457
5584
  const formAppEl = useFormAppElement();
5458
5585
  useKeyboardShortcut(keybinds, () => load(), {
5586
+ enabled: !shouldDisable,
5459
5587
  target: formAppEl,
5460
5588
  preventDefault: true
5461
5589
  });
@@ -5467,8 +5595,9 @@ function LoadAction({
5467
5595
  icon: faFolderOpen,
5468
5596
  ...otherProps,
5469
5597
  onClick: combineEventHandlers(() => load(), onClick),
5598
+ disabled: shouldDisable,
5470
5599
  loading: loading || formIsLoading,
5471
- disabled: disabled || formIsDisabled,
5600
+ enabledWhenLoading,
5472
5601
  children: label
5473
5602
  }
5474
5603
  );
@@ -5626,6 +5755,62 @@ function PathLink({
5626
5755
  }
5627
5756
  );
5628
5757
  }
5758
+ function PrintAction({
5759
+ label,
5760
+ keybinds,
5761
+ disabled,
5762
+ loading,
5763
+ enabledWhenLoading,
5764
+ onClick,
5765
+ ...otherProps
5766
+ }) {
5767
+ const [locale7] = useLocale();
5768
+ label ??= locale7.PrintAction.label;
5769
+ keybinds ??= locale7.PrintAction.keybinds;
5770
+ const printInProgress = usePrintInProgress();
5771
+ const formIsDisabled = useFormIsDisabled();
5772
+ const formIsLoading = useFormIsLoading();
5773
+ const shouldDisable = disabled || loading && !enabledWhenLoading || formIsDisabled || formIsLoading || printInProgress;
5774
+ const formAppEl = useFormAppElement();
5775
+ const formTitle = useFormTitle();
5776
+ const print = usePrint();
5777
+ const printerHasDocumentTitle = !!usePrinterDocumentTitle();
5778
+ const handlePrint = (evt) => {
5779
+ evt.preventDefault();
5780
+ void print(
5781
+ printerHasDocumentTitle ? void 0 : { documentTitle: defaultDocumentTitle(formTitle) }
5782
+ );
5783
+ };
5784
+ useKeyboardShortcut(keybinds, handlePrint, {
5785
+ enabled: !shouldDisable,
5786
+ target: formAppEl,
5787
+ preventDefault: true
5788
+ });
5789
+ return /* @__PURE__ */ jsx(
5790
+ PrinterTrigger,
5791
+ {
5792
+ onClick: combineEventHandlers(onClick, handlePrint, {
5793
+ checkDefaultPrevented: true
5794
+ }),
5795
+ children: /* @__PURE__ */ jsx(
5796
+ Button,
5797
+ {
5798
+ vertical: true,
5799
+ variant: "subtle",
5800
+ icon: faPrint,
5801
+ ...otherProps,
5802
+ loading: loading || printInProgress,
5803
+ disabled: shouldDisable,
5804
+ children: label
5805
+ }
5806
+ )
5807
+ }
5808
+ );
5809
+ }
5810
+ function defaultDocumentTitle(formTitle) {
5811
+ const date = format(/* @__PURE__ */ new Date(), "yyyy-MM-dd");
5812
+ return [formTitle, date].filter(Boolean).join(" ");
5813
+ }
5629
5814
  const RadioGroupControl = forwardRef(function RadioGroupControl2({
5630
5815
  path,
5631
5816
  options,
@@ -5782,10 +5967,11 @@ function useFormSaver({
5782
5967
  successMessage,
5783
5968
  errorMessage
5784
5969
  } = {}) {
5785
- const [locale] = useLocale();
5970
+ const [locale7] = useLocale();
5786
5971
  const formManager = useFormManager();
5787
5972
  const { getState, _setState } = useFormController();
5788
5973
  const { addToast } = useToastManager();
5974
+ const formTitle = useFormTitle();
5789
5975
  return useMemo(() => {
5790
5976
  async function save({
5791
5977
  overwrite: overwrite2,
@@ -5806,10 +5992,10 @@ function useFormSaver({
5806
5992
  throw new Error("No `encode` function was provided.");
5807
5993
  }
5808
5994
  if (successMessage2 === void 0) {
5809
- successMessage2 = locale.SaveAction.successMessage;
5995
+ successMessage2 = locale7.SaveAction.successMessage;
5810
5996
  }
5811
5997
  if (errorMessage2 === void 0) {
5812
- errorMessage2 = locale.SaveAction.errorMessage;
5998
+ errorMessage2 = locale7.SaveAction.errorMessage;
5813
5999
  }
5814
6000
  _setState({ saving: true });
5815
6001
  let fileHandle = getState().latestFileHandles?.[id2] ?? null;
@@ -5824,7 +6010,7 @@ function useFormSaver({
5824
6010
  fileHandle = await fileSave(
5825
6011
  typeof encodedForm === "string" ? new Blob([encodedForm], { type: mimeTypes2?.[0] }) : encodedForm,
5826
6012
  {
5827
- fileName: suggestedFileName,
6013
+ fileName: suggestedFileName || defaultFileName(formTitle, extensions2?.[0]),
5828
6014
  extensions: extensions2,
5829
6015
  description: description2,
5830
6016
  mimeTypes: mimeTypes2,
@@ -5895,9 +6081,11 @@ function useFormSaver({
5895
6081
  extensions,
5896
6082
  fileName,
5897
6083
  formManager,
6084
+ formTitle,
5898
6085
  getState,
5899
6086
  id,
5900
- locale.SaveAction,
6087
+ locale7.SaveAction.errorMessage,
6088
+ locale7.SaveAction.successMessage,
5901
6089
  mimeTypes,
5902
6090
  overwrite,
5903
6091
  path,
@@ -5909,6 +6097,10 @@ function useFormSaver({
5909
6097
  function useFormIsSaving() {
5910
6098
  return useFormController().useState((state) => state.saving);
5911
6099
  }
6100
+ function defaultFileName(formTitle, extension) {
6101
+ const date = format(/* @__PURE__ */ new Date(), "yyyy-MM-dd");
6102
+ return [[formTitle, date].filter(Boolean).join(" "), extension].filter(Boolean).join("");
6103
+ }
5912
6104
  function SaveAction({
5913
6105
  label,
5914
6106
  keybinds,
@@ -5917,6 +6109,7 @@ function SaveAction({
5917
6109
  saveAsLabel,
5918
6110
  saveAsKeybinds,
5919
6111
  loading,
6112
+ enabledWhenLoading,
5920
6113
  disabled,
5921
6114
  onClick,
5922
6115
  variant = "subtle",
@@ -5936,12 +6129,12 @@ function SaveAction({
5936
6129
  dropdownMenuProps,
5937
6130
  ...otherProps
5938
6131
  }) {
5939
- const [locale] = useLocale();
5940
- label ??= locale.SaveAction.label;
5941
- keybinds ??= locale.SaveAction.keybinds;
5942
- saveOptionsLabel ??= locale.SaveAction.saveOptionsLabel;
5943
- saveAsLabel ??= locale.SaveAction.saveAsLabel;
5944
- saveAsKeybinds ??= locale.SaveAction.saveAsKeybinds;
6132
+ const [locale7] = useLocale();
6133
+ label ??= locale7.SaveAction.label;
6134
+ keybinds ??= locale7.SaveAction.keybinds;
6135
+ saveOptionsLabel ??= locale7.SaveAction.saveOptionsLabel;
6136
+ saveAsLabel ??= locale7.SaveAction.saveAsLabel;
6137
+ saveAsKeybinds ??= locale7.SaveAction.saveAsKeybinds;
5945
6138
  const { save, supportsFileSystemAPIs } = useFormSaver({
5946
6139
  path,
5947
6140
  encode,
@@ -5957,12 +6150,15 @@ function SaveAction({
5957
6150
  });
5958
6151
  const formIsSaving = useFormIsSaving();
5959
6152
  const formIsLoading = useFormIsLoading();
6153
+ const shouldDisable = disabled || loading && !enabledWhenLoading || formIsSaving || formIsLoading;
5960
6154
  const formAppEl = useFormAppElement();
5961
6155
  useKeyboardShortcut(keybinds, () => save({ overwrite: !disableOverwrite }), {
6156
+ enabled: !shouldDisable,
5962
6157
  target: formAppEl,
5963
6158
  preventDefault: true
5964
6159
  });
5965
6160
  useKeyboardShortcut(saveAsKeybinds, () => save(), {
6161
+ enabled: !shouldDisable,
5966
6162
  target: formAppEl,
5967
6163
  preventDefault: true
5968
6164
  });
@@ -5978,8 +6174,9 @@ function SaveAction({
5978
6174
  () => save({ overwrite: !disableOverwrite }),
5979
6175
  onClick
5980
6176
  ),
6177
+ disabled: shouldDisable,
5981
6178
  loading: loading || formIsSaving,
5982
- disabled: disabled || formIsLoading,
6179
+ enabledWhenLoading,
5983
6180
  children: label
5984
6181
  }
5985
6182
  );
@@ -5994,18 +6191,11 @@ function SaveAction({
5994
6191
  icon: faCaretDown,
5995
6192
  ...saveOptionsProps,
5996
6193
  label: saveOptionsLabel,
5997
- disabled: disabled || loading || formIsSaving || formIsLoading || saveOptionsProps?.disabled,
6194
+ disabled: shouldDisable || saveOptionsProps?.disabled,
5998
6195
  style: { minWidth: 20, ...saveOptionsProps?.style }
5999
6196
  }
6000
6197
  ) }),
6001
- /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", ...dropdownMenuProps, children: /* @__PURE__ */ jsx(
6002
- DropdownMenuItem,
6003
- {
6004
- onClick: () => save(),
6005
- disabled: disabled || loading || formIsSaving || formIsLoading,
6006
- children: saveAsLabel
6007
- }
6008
- ) })
6198
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", ...dropdownMenuProps, children: /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => save(), disabled: shouldDisable, children: saveAsLabel }) })
6009
6199
  ] })
6010
6200
  ] }) : saveButton;
6011
6201
  }
@@ -6337,6 +6527,7 @@ function SubmitAction({
6337
6527
  keybinds,
6338
6528
  confirmWarnings = true,
6339
6529
  loading,
6530
+ enabledWhenLoading,
6340
6531
  disabled,
6341
6532
  onClick,
6342
6533
  dialogTitle,
@@ -6360,20 +6551,20 @@ function SubmitAction({
6360
6551
  ...otherProps
6361
6552
  }) {
6362
6553
  const prefix = usePrefix();
6363
- const [locale] = useLocale();
6364
- label ??= locale.SubmitAction.label;
6365
- keybinds ??= locale.SubmitAction.keybinds;
6366
- dialogTitle ??= locale.SubmitAction.dialogTitle;
6367
- dialogDescription ??= locale.SubmitAction.dialogDescription;
6368
- dialogBody ??= locale.SubmitAction.dialogBody;
6369
- confirmWarningsCheckboxLabel ??= locale.SubmitAction.confirmWarningsCheckboxLabel;
6370
- dialogOkText ??= locale.SubmitAction.dialogOkText ?? label;
6371
- dialogCancelText ??= locale.SubmitAction.dialogCancelText;
6554
+ const [locale7] = useLocale();
6555
+ label ??= locale7.SubmitAction.label;
6556
+ keybinds ??= locale7.SubmitAction.keybinds;
6557
+ dialogTitle ??= locale7.SubmitAction.dialogTitle;
6558
+ dialogDescription ??= locale7.SubmitAction.dialogDescription;
6559
+ dialogBody ??= locale7.SubmitAction.dialogBody;
6560
+ confirmWarningsCheckboxLabel ??= locale7.SubmitAction.confirmWarningsCheckboxLabel;
6561
+ dialogOkText ??= locale7.SubmitAction.dialogOkText ?? label;
6562
+ dialogCancelText ??= locale7.SubmitAction.dialogCancelText;
6372
6563
  if (successMessage === void 0) {
6373
- successMessage = locale.SubmitAction.successMessage;
6564
+ successMessage = locale7.SubmitAction.successMessage;
6374
6565
  }
6375
6566
  if (errorMessage === void 0) {
6376
- errorMessage = locale.SubmitAction.errorMessage;
6567
+ errorMessage = locale7.SubmitAction.errorMessage;
6377
6568
  }
6378
6569
  const [confirmingSubmission, setConfirmingSubmission] = useState(false);
6379
6570
  const startIssuesNavigation = useStartIssuesNavigation();
@@ -6381,9 +6572,10 @@ function SubmitAction({
6381
6572
  const { submit, useSubmitting } = useFormController();
6382
6573
  const submitting = useSubmitting();
6383
6574
  const [runningOnSubmit, setRunningOnSubmit] = useState(false);
6384
- const formIsLoading = useFormIsLoading();
6385
6575
  const formIsDisabled = useFormIsDisabled();
6576
+ const formIsLoading = useFormIsLoading();
6386
6577
  const formAppEl = useFormAppElement();
6578
+ const shouldDisable = disabled || loading && !enabledWhenLoading || formIsDisabled || formIsLoading || submitting;
6387
6579
  const [submissionInfo, setSubmissionInfo] = useState(null);
6388
6580
  const [checkedWarnings, setCheckedWarnings] = useState([]);
6389
6581
  const allWarningsChecked = !submissionInfo?.warnings || submissionInfo.warnings.every(
@@ -6461,6 +6653,7 @@ function SubmitAction({
6461
6653
  convertExternalIssuesTableRowIndicesToIds
6462
6654
  });
6463
6655
  useKeyboardShortcut(keybinds, handleAction, {
6656
+ enabled: !shouldDisable,
6464
6657
  target: formAppEl,
6465
6658
  preventDefault: true
6466
6659
  });
@@ -6474,8 +6667,9 @@ function SubmitAction({
6474
6667
  iconPlacement: "end",
6475
6668
  ...otherProps,
6476
6669
  onClick: combineEventHandlers(handleAction, onClick),
6670
+ disabled: shouldDisable,
6477
6671
  loading: loading || submitting,
6478
- disabled: disabled || formIsDisabled || formIsLoading,
6672
+ enabledWhenLoading,
6479
6673
  children: label
6480
6674
  }
6481
6675
  ) }),
@@ -6567,13 +6761,14 @@ function useTableControlRowContext() {
6567
6761
  return tableControlRowContext;
6568
6762
  }
6569
6763
  const TableControlCell = forwardRef(function TableControlCell2({ variant, ...otherProps }, forwardedRef) {
6764
+ const printing = usePrinting();
6570
6765
  const { useDisplayStatus } = useTableControlRowContext();
6571
6766
  const deferredDisplayStatus = useDeferredValue(useDisplayStatus());
6572
6767
  return /* @__PURE__ */ jsx(
6573
6768
  DataTableCell,
6574
6769
  {
6575
6770
  variant,
6576
- status: variant === "header" ? displayStatusToControlStatus(deferredDisplayStatus) : void 0,
6771
+ status: !printing && variant === "header" ? displayStatusToControlStatus(deferredDisplayStatus) : void 0,
6577
6772
  ...otherProps,
6578
6773
  ref: forwardedRef
6579
6774
  }
@@ -6588,6 +6783,13 @@ const TableControlRow = memo(
6588
6783
  const path = controller.usePath();
6589
6784
  useRegisterController(controller);
6590
6785
  useRegisterLabel(path, row == null ? null : index + 1);
6786
+ const initialized = controller.useInitialized();
6787
+ const finishPrintingTask = useStartPrintingTask({ enabled: row != null });
6788
+ useEffect(() => {
6789
+ if (initialized) {
6790
+ finishPrintingTask();
6791
+ }
6792
+ }, [finishPrintingTask, initialized]);
6591
6793
  return /* @__PURE__ */ jsx(CurrentPath, { path, children: /* @__PURE__ */ jsx(
6592
6794
  TableControlRowContext.Provider,
6593
6795
  {
@@ -6770,12 +6972,14 @@ const TableControl = forwardRef(function TableControl2({
6770
6972
  [absolutePath, exists, goToId]
6771
6973
  )
6772
6974
  );
6975
+ const printing = usePrinting();
6773
6976
  const dataTableColumns = useMemo(
6774
6977
  () => tableControlToDataTableColumns(columns, {
6775
6978
  disabled: controlIsDisabled,
6776
- readOnly: controlIsReadOnly
6979
+ readOnly: controlIsReadOnly,
6980
+ printing
6777
6981
  }),
6778
- [columns, controlIsDisabled, controlIsReadOnly]
6982
+ [columns, controlIsDisabled, controlIsReadOnly, printing]
6779
6983
  );
6780
6984
  const tableControlController = useMemo(
6781
6985
  () => ({ ...controller, ...ownController }),
@@ -6812,6 +7016,7 @@ const TableControl = forwardRef(function TableControl2({
6812
7016
  loading: !initialized,
6813
7017
  renderRow: (props) => /* @__PURE__ */ jsx(TableControlRow, { ...props }),
6814
7018
  renderCell: (props) => /* @__PURE__ */ jsx(TableControlCell, { ...props }),
7019
+ showAllRowsWhilePrinting: true,
6815
7020
  apiRef: dataTableApiRef,
6816
7021
  ...otherProps,
6817
7022
  ref: forwardedRef
@@ -6854,6 +7059,7 @@ const TableControlAddRowTrigger = forwardRef(function TableControlAddRowTrigger2
6854
7059
  defaultButtonText,
6855
7060
  onRowAdded,
6856
7061
  showWhenReadOnly,
7062
+ showWhilePrinting,
6857
7063
  disabled,
6858
7064
  onClick,
6859
7065
  className,
@@ -6861,8 +7067,9 @@ const TableControlAddRowTrigger = forwardRef(function TableControlAddRowTrigger2
6861
7067
  ...otherProps
6862
7068
  }, forwardedRef) {
6863
7069
  const prefix = usePrefix();
6864
- const [locale] = useLocale();
6865
- defaultButtonText ??= locale.TableControlAddRowTrigger.defaultButtonText;
7070
+ const [locale7] = useLocale();
7071
+ defaultButtonText ??= locale7.TableControlAddRowTrigger.defaultButtonText;
7072
+ const printing = usePrinting();
6866
7073
  const { controller, size, maxRows } = useTableControlContext();
6867
7074
  const controlIsDisabled = useFormIsDisabled();
6868
7075
  const controlIsReadOnly = useFormIsReadOnly();
@@ -6876,7 +7083,7 @@ const TableControlAddRowTrigger = forwardRef(function TableControlAddRowTrigger2
6876
7083
  ({ initialized, exists }) => !initialized || !exists || controlIsDisabled || disabled || controlIsReadOnly || maxRows != null && size >= maxRows
6877
7084
  );
6878
7085
  const As = Slot;
6879
- return (showWhenReadOnly || !controlIsReadOnly) && /* @__PURE__ */ jsx(
7086
+ return (showWhenReadOnly || !controlIsReadOnly) && (showWhilePrinting || !printing) && /* @__PURE__ */ jsx(
6880
7087
  As,
6881
7088
  {
6882
7089
  className: cx(prefix("table-control__add-row-trigger"), className),
@@ -6908,12 +7115,12 @@ const TableControlRemoveRowTrigger = forwardRef(function TableControlRemoveRowTr
6908
7115
  children,
6909
7116
  ...otherProps
6910
7117
  }, forwardedRef) {
6911
- const [locale] = useLocale();
6912
- defaultButtonLabel ??= locale.TableControlRemoveRowTrigger.defaultButtonLabel;
6913
- confirmDialogTitle ??= locale.TableControlRemoveRowTrigger.confirmDialogTitle;
6914
- confirmDialogMessage ??= locale.TableControlRemoveRowTrigger.confirmDialogMessage;
6915
- confirmDialogOkText ??= locale.TableControlRemoveRowTrigger.confirmDialogOkText;
6916
- confirmDialogCancelText ??= locale.TableControlRemoveRowTrigger.confirmDialogCancelText;
7118
+ const [locale7] = useLocale();
7119
+ defaultButtonLabel ??= locale7.TableControlRemoveRowTrigger.defaultButtonLabel;
7120
+ confirmDialogTitle ??= locale7.TableControlRemoveRowTrigger.confirmDialogTitle;
7121
+ confirmDialogMessage ??= locale7.TableControlRemoveRowTrigger.confirmDialogMessage;
7122
+ confirmDialogOkText ??= locale7.TableControlRemoveRowTrigger.confirmDialogOkText;
7123
+ confirmDialogCancelText ??= locale7.TableControlRemoveRowTrigger.confirmDialogCancelText;
6917
7124
  const { confirm } = useAlertDialog();
6918
7125
  const { controller } = useTableControlContext();
6919
7126
  const controlIsDisabled = useFormIsDisabled();
@@ -6978,7 +7185,7 @@ function tableControlActionsColumn({
6978
7185
  removeRowProps,
6979
7186
  ...columnOverrides
6980
7187
  } = {}) {
6981
- return (tableControlStatus) => !tableControlStatus.readOnly && {
7188
+ return (tableControlStatus) => !tableControlStatus.readOnly && !tableControlStatus.printing && {
6982
7189
  sticky: "right",
6983
7190
  width: 50,
6984
7191
  fixed: true,
@@ -6996,13 +7203,14 @@ const TableControlContent = forwardRef(function TableControlContent2({ container
6996
7203
  void controller.setTouched();
6997
7204
  }
6998
7205
  }, [controller]);
7206
+ const printing = usePrinting();
6999
7207
  const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());
7000
7208
  return /* @__PURE__ */ jsx(
7001
7209
  DataTableContent,
7002
7210
  {
7003
7211
  editable: true,
7004
7212
  variant: "control",
7005
- status: displayStatusToControlStatus(deferredDisplayStatus),
7213
+ status: printing ? void 0 : displayStatusToControlStatus(deferredDisplayStatus),
7006
7214
  containerProps: {
7007
7215
  ...containerProps,
7008
7216
  className: cx(
@@ -7154,6 +7362,7 @@ function parseText(formattedValue, state) {
7154
7362
  const TopBar = forwardRef(
7155
7363
  function TopBar2({ className, ...otherProps }, forwardedRef) {
7156
7364
  const prefix = usePrefix();
7365
+ const { printHidden } = usePrintClassNames();
7157
7366
  const setTopBarHeight = useSetTopBarHeight();
7158
7367
  const [topBarEl, setTopBarEl] = useState(null);
7159
7368
  useMeasure(
@@ -7167,7 +7376,7 @@ const TopBar = forwardRef(
7167
7376
  return /* @__PURE__ */ jsx(PortalContext.Provider, { value: { container: topBarEl }, children: /* @__PURE__ */ jsx(
7168
7377
  "div",
7169
7378
  {
7170
- className: cx(prefix("top-bar"), className),
7379
+ className: cx(prefix("top-bar"), printHidden, className),
7171
7380
  ...otherProps,
7172
7381
  ref: combinedTopBarRef
7173
7382
  }
@@ -7192,19 +7401,23 @@ function ValidateAction({
7192
7401
  label,
7193
7402
  keybinds,
7194
7403
  loading,
7404
+ enabledWhenLoading,
7195
7405
  disabled,
7196
7406
  onClick,
7197
7407
  ...otherProps
7198
7408
  }) {
7199
- const [locale] = useLocale();
7200
- label ??= locale.ValidateAction.label;
7201
- keybinds ??= locale.ValidateAction.keybinds;
7409
+ const [locale7] = useLocale();
7410
+ label ??= locale7.ValidateAction.label;
7411
+ keybinds ??= locale7.ValidateAction.keybinds;
7202
7412
  const { validate } = useFormValidator();
7203
- const { validatingAutomatically, validating } = useFormIsValidating();
7413
+ const { validatingAutomatically, validatingManually, validating } = useFormIsValidating();
7204
7414
  const deferredValidating = useDeferredValue(validating);
7415
+ const formIsDisabled = useFormIsDisabled();
7205
7416
  const formIsLoading = useFormIsLoading();
7417
+ const shouldDisable = disabled || loading && !enabledWhenLoading || formIsDisabled || formIsLoading || validatingManually;
7206
7418
  const formAppEl = useFormAppElement();
7207
7419
  useKeyboardShortcut(keybinds, validate, {
7420
+ enabled: !shouldDisable,
7208
7421
  target: formAppEl,
7209
7422
  preventDefault: true
7210
7423
  });
@@ -7216,9 +7429,9 @@ function ValidateAction({
7216
7429
  vertical: true,
7217
7430
  ...otherProps,
7218
7431
  onClick: combineEventHandlers(validate, onClick),
7219
- disabled: disabled || formIsLoading,
7432
+ disabled: shouldDisable,
7220
7433
  loading: loading || deferredValidating,
7221
- enabledWhenLoading: validatingAutomatically,
7434
+ enabledWhenLoading: enabledWhenLoading || validatingAutomatically,
7222
7435
  children: label
7223
7436
  }
7224
7437
  );
@@ -7258,6 +7471,7 @@ export {
7258
7471
  PathLink,
7259
7472
  PrefixSuffixContext,
7260
7473
  PrefixSuffixProvider,
7474
+ PrintAction,
7261
7475
  RadioGroupControl,
7262
7476
  RepetitiveAnnexRegistrar,
7263
7477
  SaveAction,
@@ -7277,10 +7491,12 @@ export {
7277
7491
  ValidateAction,
7278
7492
  displayStatusToColor,
7279
7493
  displayStatusToControlStatus,
7280
- enGB,
7281
- enUS,
7282
- fr,
7283
- pt,
7494
+ locale as enGB,
7495
+ locale2 as enUS,
7496
+ locale3 as fr,
7497
+ locale4 as frFR,
7498
+ locale5 as pt,
7499
+ locale6 as ptPT,
7284
7500
  setDefaultPrefixSuffix,
7285
7501
  tableControlActionsColumn,
7286
7502
  tableControlIndexColumn,
@@ -7297,6 +7513,7 @@ export {
7297
7513
  useFormIsValidating,
7298
7514
  useFormLoader,
7299
7515
  useFormSaver,
7516
+ useFormTitle,
7300
7517
  useFormValidator,
7301
7518
  useIsInControlField,
7302
7519
  useIsRegistered,