@ostack.tech/ui-kform 0.6.1 → 0.6.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ostack-ui-kform.js","sources":["../src/providers/PrefixSuffixProvider/defaultPrefixSuffix.ts","../src/providers/PrefixSuffixProvider/PrefixSuffixContext.ts","../src/providers/PrefixSuffixProvider/PrefixSuffixProvider.tsx","../src/providers/PrefixSuffixProvider/usePrefix.ts","../src/providers/ActivePathProvider/ActivePathContext.ts","../src/providers/ActivePathProvider/ActivePathProvider.tsx","../src/providers/LocalizationProvider/LocalizationContext.ts","../src/providers/LocalizationProvider/LocalizationProvider.tsx","../src/providers/LocalizationProvider/useLocale.ts","../src/utils/pathSpecificity.ts","../src/utils/useEqualityFn.ts","../src/components/FormApp/FormAppContext.ts","../src/utils/useControlAutofocus.ts","../src/components/FormApp/FormAppAutoFocus.tsx","../src/components/FormApp/FormAppElement.tsx","../src/components/FormApp/FormAppIssueMessages.tsx","../src/components/FormApp/FormApp.tsx","../src/components/FormApp/FormAppStatus.tsx","../src/utils/mostSpecificPath.ts","../src/components/Annexes/AnnexesContext.ts","../src/components/Annexes/Annex.tsx","../src/utils/useFormLoader.tsx","../src/components/Annexes/AnnexRegistrar.tsx","../src/components/Annexes/RepetitiveAnnexRegistrar.tsx","../src/components/Annexes/Annexes.tsx","../src/utils/useReportValidationFailures.ts","../src/components/ControlField/ControlFieldContext.ts","../src/components/ControlField/ControlField.tsx","../src/components/IssueMessage/IssueMessage.tsx","../src/components/IssueMessages/IssueMessages.tsx","../src/components/IssuesPopover/IssuesPopover.tsx","../src/utils/displayStatusConversions.ts","../src/components/Annexes/AnnexesMenu.tsx","../src/components/Annexes/AnnexTab.tsx","../src/components/Annexes/AnnexesTabList.tsx","../src/components/Annexes/AnnexesManager.tsx","../src/utils/useControlIssues.tsx","../src/utils/useRegisterControl.tsx","../src/components/CheckboxControl/CheckboxControl.tsx","../src/utils/selectionTransformations.tsx","../src/components/CheckboxGroupControl/CheckboxGroupControl.tsx","../src/utils/dateRestrictions.ts","../src/utils/useTemporalStringTransformer.ts","../src/components/DateControl/DateControl.tsx","../src/components/DateRangeControl/DateRangeControl.tsx","../src/components/FileControl/FileControl.tsx","../src/components/FormPages/FormPagesContext.ts","../src/components/FormPages/FormPageHeader.tsx","../src/components/FormPages/FormPage.tsx","../src/components/FormPages/FormPageRegistrar.tsx","../src/components/FormPages/FormPages.tsx","../src/components/FormPages/FormPagesSelectOption.tsx","../src/components/FormPages/FormPagesSelect.tsx","../src/components/FormPages/FormPageSidebarItem.tsx","../src/components/FormPages/FormPagesSidebar.tsx","../src/components/FormPages/FormPagesNavigation.tsx","../src/components/FormStepper/FormStepperContext.ts","../src/components/FormStepper/FormStepContent.tsx","../src/components/FormStepper/FormStep.tsx","../src/components/FormStepper/FormStepList.tsx","../src/components/FormStepper/FormStepRegistrar.tsx","../src/components/FormStepper/FormStepper.tsx","../src/components/IssueAlert/IssueAlert.tsx","../src/utils/useFormValidator.ts","../src/components/IssuesPanel/IssuesPanelControls.tsx","../src/components/IssuesPanel/IssuesPanelMessagesCard.tsx","../src/components/IssuesPanel/IssuesPanelSummaryCard.tsx","../src/components/IssuesPanel/IssuesPanel.tsx","../src/components/LoadAction/LoadAction.tsx","../src/components/NumericControl/NumericControl.tsx","../src/components/PathLink/PathLink.tsx","../src/components/PrintAction/PrintAction.tsx","../src/components/RadioGroupControl/RadioGroupControl.tsx","../src/utils/useFormSaver.tsx","../src/components/SaveAction/SaveAction.tsx","../src/components/SelectControl/SelectControl.tsx","../src/components/SelectMultipleControl/SelectMultipleControl.tsx","../src/components/SubmitAction/SubmitAction.tsx","../src/components/TableControl/TableControlContext.ts","../src/components/TableControl/TableControlCell.tsx","../src/components/TableControl/TableControlRow.tsx","../src/components/TableControl/TableControl.tsx","../src/components/TableControl/TableControlAddRowTrigger.tsx","../src/components/TableControl/TableControlApi.ts","../src/components/TableControl/TableControlRemoveRowTrigger.tsx","../src/components/TableControl/TableControlColumn.tsx","../src/components/TableControl/TableControlContent.tsx","../src/components/TableControl/TableControlPagination.tsx","../src/components/TableControl/TableControlRowsPerPage.tsx","../src/components/TextControl/TextControl.tsx","../src/components/TopBar/TopBar.tsx","../src/components/TopBar/TopBarActions.tsx","../src/components/ValidateAction/ValidateAction.tsx"],"sourcesContent":["import { createStore } from \"zustand\";\n\n/** Initial default library prefix-suffix. */\nconst DEFAULT_PREFIX_SUFFIX = \"kform-\";\n\n/** Store holding the default prefix-suffix. */\nexport const defaultPrefixSuffixStore = createStore(() => ({\n defaultPrefixSuffix: DEFAULT_PREFIX_SUFFIX,\n}));\n\n/**\n * Function used to set the default library's prefix-suffix. The default library\n * prefix-suffix can be overridden by providing a `prefixSuffix` property to the\n * `PrefixSuffixProvider` or `FormApp` components.\n *\n * @param defaultPrefixSuffix Prefix-suffix to set as the library's default.\n */\nexport function setDefaultPrefixSuffix(defaultPrefixSuffix: string) {\n defaultPrefixSuffixStore.setState({ defaultPrefixSuffix });\n}\n","import { createContext } from \"react\";\n\n/** Prefix-suffix context. */\nexport const PrefixSuffixContext = createContext<string | null>(null);\n","import type { ReactNode } from \"react\";\n\nimport { PrefixSuffixContext } from \"./PrefixSuffixContext.ts\";\n\n/** Properties of the prefix-suffix provider. */\nexport interface PrefixSuffixProviderProps {\n /** Suffix to add to ostack/UI's prefix. */\n prefixSuffix?: string;\n children: ReactNode;\n}\n\n/** Prefix-suffix provider. */\nexport function PrefixSuffixProvider({\n prefixSuffix,\n children,\n}: PrefixSuffixProviderProps) {\n return prefixSuffix === undefined ? (\n children\n ) : (\n <PrefixSuffixContext.Provider value={prefixSuffix}>\n {children}\n </PrefixSuffixContext.Provider>\n );\n}\n","import { type PrefixFn, usePrefix as useUiPrefix } from \"@ostack.tech/ui\";\nimport { useCallback, useContext } from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { defaultPrefixSuffixStore } from \"./defaultPrefixSuffix.ts\";\nimport { PrefixSuffixContext } from \"./PrefixSuffixContext.ts\";\n\n/**\n * Hook which returns a function which can be used to prefix a string with the\n * current prefix.\n */\nexport function usePrefix(): PrefixFn {\n const prefix = useUiPrefix();\n const defaultPrefixSuffix = useStore(\n defaultPrefixSuffixStore,\n ({ defaultPrefixSuffix }) => defaultPrefixSuffix,\n );\n const prefixSuffix = useContext(PrefixSuffixContext) ?? defaultPrefixSuffix;\n return useCallback(\n (toPrefix = \"\") => prefix(`${prefixSuffix}${toPrefix}`),\n [prefix, prefixSuffix],\n );\n}\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { createContext, useContext } from \"react\";\n\n/** Value of the active path context. */\nexport interface ActivePathContextValue {\n activePath: AbsolutePath;\n onActivePathChange: (activePath: AbsolutePath | string | null) => void;\n}\n\n/** Active path context. */\nexport const ActivePathContext = createContext<ActivePathContextValue | null>(\n null,\n);\n\n/** Hook providing access to the active path context. */\nexport function useActivePathContext(): ActivePathContextValue {\n const activePathContext = useContext(ActivePathContext);\n if (!activePathContext) {\n throw new Error(\"Active path context not in scope\");\n }\n return activePathContext;\n}\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n type Path,\n} from \"@ostack.tech/kform\";\nimport { useResolvedPath } from \"@ostack.tech/kform-react\";\nimport { useControllableState, useLatestValues } from \"@ostack.tech/ui\";\nimport { type ReactNode, useCallback, useMemo } from \"react\";\n\nimport { ActivePathContext } from \"./ActivePathContext.ts\";\n\n/**\n * Navigation options to use when controlling the active path via the browser's\n * URL.\n */\nexport interface OnActivePathChangeNavigationOptions {\n /** Whether to replace the current history entry. */\n replace: boolean;\n}\n\n/** Properties of the active path provider. */\nexport interface ActivePathProviderProps {\n /** Uncontrolled default active path to use. */\n defaultActivePath?: string | Path;\n /** Controlled active path to use. */\n activePath?: string | Path;\n /**\n * Callback called whenever the active path is changed.\n *\n * @param activePath New active path.\n * @param options Navigation options to use when controlling the active path\n * via the browser's URL.\n */\n onActivePathChange?: (\n activePath: AbsolutePath,\n options: OnActivePathChangeNavigationOptions,\n ) => void;\n children?: ReactNode;\n}\n\n/** Provider which controls the active path in a section of a form. */\nexport function ActivePathProvider({\n defaultActivePath,\n activePath: controlledActivePath,\n onActivePathChange,\n children,\n}: ActivePathProviderProps) {\n const [activePath, setActivePath] = useControllableState(\n defaultActivePath,\n controlledActivePath,\n );\n const resolvedActivePath = useResolvedPath(activePath);\n\n const latest = useLatestValues({ resolvedActivePath, onActivePathChange });\n const handleActivePathChange = useCallback(\n (newActivePath: AbsolutePath | string | null) => {\n const activePath = latest.resolvedActivePath;\n if (typeof newActivePath === \"string\") {\n newActivePath = new AbsolutePath(newActivePath);\n } else {\n newActivePath ??= AbsolutePath.ROOT;\n }\n\n // Ignore when new path is equal to or an ancestor of the old one\n if (\n !activePath.equals(newActivePath) &&\n !newActivePath\n .append(AbsolutePathFragment.RecursiveWildcard)\n .contains(activePath)\n ) {\n // Replace when the old path is an ancestor of the new one\n const replace = activePath\n .append(AbsolutePathFragment.RecursiveWildcard)\n .contains(newActivePath);\n setActivePath(newActivePath);\n latest.onActivePathChange?.(newActivePath, { replace });\n }\n },\n [latest, setActivePath],\n );\n\n return (\n <ActivePathContext.Provider\n value={useMemo(\n () => ({\n activePath: resolvedActivePath,\n onActivePathChange: handleActivePathChange,\n }),\n [handleActivePathChange, resolvedActivePath],\n )}\n >\n {children}\n </ActivePathContext.Provider>\n );\n}\n","import { createContext } from \"react\";\n\nimport type { LocalizationObject } from \"./LocalizationObject.ts\";\n\n/** Value of the localisation context. */\nexport interface LocalizationContextValue {\n locale: LocalizationObject;\n setLocale: (locale: LocalizationObject) => void;\n}\n\n/** Localisation context. */\nexport const LocalizationContext =\n createContext<LocalizationContextValue | null>(null);\n","import {\n combineEventHandlers,\n LocalizationProvider as UiLocalizationProvider,\n useControllableState,\n} from \"@ostack.tech/ui\";\nimport type { ReactNode } from \"react\";\n\nimport { LocalizationContext } from \"./LocalizationContext.ts\";\nimport type { LocalizationObject } from \"./LocalizationObject.ts\";\n\n/** Properties of the localisation provider. */\nexport interface LocalizationProviderProps {\n /** Uncontrolled locale to use. */\n defaultLocale?: LocalizationObject;\n /** Controlled locale to use. */\n locale?: LocalizationObject;\n /**\n * Function called when the locale changes.\n *\n * @param locale New locale.\n */\n onLocaleChange?: (locale: LocalizationObject) => void;\n children: ReactNode;\n}\n\n/**\n * Localisation provider (also sets the `@ostack.tech/ui` localisation\n * provider).\n */\nexport function LocalizationProvider({\n defaultLocale,\n locale: controlledLocale,\n onLocaleChange,\n children,\n}: LocalizationProviderProps) {\n const [locale, setLocale] = useControllableState(\n defaultLocale,\n controlledLocale,\n );\n\n return locale === undefined ? (\n children\n ) : (\n <LocalizationContext.Provider\n value={{\n locale,\n setLocale: combineEventHandlers(setLocale, onLocaleChange),\n }}\n >\n <UiLocalizationProvider locale={locale.baseLocale}>\n {children}\n </UiLocalizationProvider>\n </LocalizationContext.Provider>\n );\n}\n","import { useContext, useMemo } from \"react\";\n\nimport { LocalizationContext } from \"./LocalizationContext.ts\";\nimport type { LocalizationObject } from \"./LocalizationObject.ts\";\n\n/** Hook used to get and set the current locale. */\nexport function useLocale(): [\n LocalizationObject,\n (locale: LocalizationObject) => void,\n] {\n const localizationContext = useContext(LocalizationContext);\n if (localizationContext === null)\n throw new Error(\n \"No locale has been provided. Please provide a locale via the \" +\n \"`FormApp` or `LocalizationProvider` components.\",\n );\n return useMemo(\n () => [localizationContext.locale, localizationContext.setLocale],\n [localizationContext.locale, localizationContext.setLocale],\n );\n}\n","import { type AbsolutePath, AbsolutePathFragment } from \"@ostack.tech/kform\";\n\ntype PathSpecificity = [number, number, number];\n\n/**\n * Given two paths, returns a number > 0 if the first path is more specific than\n * the second, a number < 0 if the first path is less specific than the second,\n * or 0 if both paths have the same specificity.\n *\n * Specificity is not incredibly well specified (and may change over time if a\n * need arises), but the idea is that wildcards make paths less specific, so\n * `/a/∗` is less specific than `/a/b`, and `/∗∗` is the least specific path.\n *\n * Both `/a` and `/a/b/c` have the same specificity since both paths uniquely\n * identify a resource.\n *\n * @param path1 First path to compare.\n * @param path2 Second path to compare.\n * @returns Number representing which path is more specific.\n */\nexport function comparePathsBySpecificity(\n path1: AbsolutePath,\n path2: AbsolutePath,\n) {\n const [ids1, wildcards1, recursiveWildcards1] = pathSpecificity(path1);\n const [ids2, wildcards2, recursiveWildcards2] = pathSpecificity(path2);\n // When neither path has recursive wildcards, the most specific one is the one\n // with the least non-recursive wildcards\n if (recursiveWildcards1 === 0 && recursiveWildcards2 === 0) {\n return wildcards2 - wildcards1;\n }\n // When one path has recursive wildcards but the other one doesn't, the most\n // specific one is the one without recursive wildcards\n if (recursiveWildcards1 === 0 || recursiveWildcards2 === 0) {\n return recursiveWildcards2 - recursiveWildcards1;\n }\n // When both paths have recursive wildcards, the most specific one is the one\n // with the most identifiers; if the number of identifiers is the same, then\n // the one with the most non-recursive wildcards\n return ids1 - ids2 || wildcards1 - wildcards2;\n}\n\nfunction pathSpecificity(path: AbsolutePath): PathSpecificity {\n const specificity: PathSpecificity = [0, 0, 0];\n for (const fragment of path.fragments) {\n if (fragment instanceof AbsolutePathFragment.Id) {\n ++specificity[0];\n } else if (fragment === AbsolutePathFragment.Wildcard) {\n ++specificity[1];\n } else if (fragment === AbsolutePathFragment.RecursiveWildcard) {\n ++specificity[2];\n }\n }\n return specificity;\n}\n","import { useRef } from \"react\";\n\nconst INITIAL = Symbol();\n\n// TODO: This is repeated both here and in `@ostack.tech/kform-react`, it might\n// make sense to either export and use the `@ostack.tech/kform-react` version\n// or upstream it instead\nexport function useEqualityFn<TState, TResult>(\n selector: (state: TState) => TResult,\n equalityFn: (v1: TResult, v2: TResult) => boolean = Object.is,\n): (state: TState) => TResult {\n const latest = useRef<TResult | typeof INITIAL>(INITIAL);\n return (state) => {\n const next = selector(state);\n return latest.current !== INITIAL && equalityFn(latest.current, next)\n ? latest.current\n : (latest.current = next);\n };\n}\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n type Path,\n PathMultimap,\n type PathMultimapEntryId,\n} from \"@ostack.tech/kform\";\nimport { type Controller, equals } from \"@ostack.tech/kform-react\";\nimport { useConstant, useLatestValues, usePrinting } from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { useShallow } from \"zustand/react/shallow\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { comparePathsBySpecificity } from \"../../utils/pathSpecificity.ts\";\nimport { useEqualityFn } from \"../../utils/useEqualityFn.ts\";\nimport type { IssueMessagesByCode, IssueMessageValue } from \"../IssueMessages\";\nimport type { IssuesDisplayMode } from \"./FormApp.tsx\";\n\n/** Value of the form app context. */\nexport interface FormAppContextValue<T = unknown> {\n formTitle?: string;\n disabled: boolean;\n readOnly: boolean;\n issuesDisplayMode: IssuesDisplayMode;\n displayIssueCodes: boolean;\n formAppElement: HTMLFormElement | null;\n store: FormAppStore<T>;\n}\n\n/** State of the form app. */\nexport interface FormAppState<T> {\n controller: Controller<T>;\n focusedPath: AbsolutePath | null;\n focusCounter: number;\n issuesPanelPath: AbsolutePath | null;\n topBarHeight: number;\n leftSidebarWidth: number;\n bottomPanelHeight: number;\n startIssuesNavigation?: () => void;\n latestInteraction: AbsolutePath;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new multimap\n // instances\n registeredControllers: [PathMultimap<Controller>];\n registeredIssueMessages: [\n PathMultimap<{ messages: IssueMessagesByCode; priority: number }>,\n ];\n deferredIssueMessageRemovalEntryIds: PathMultimapEntryId[];\n registeredLabels: [PathMultimap<{ label: ReactNode; priority: number }>];\n deferredLabelRemovalEntryIds: PathMultimapEntryId[];\n actions: FormAppActions;\n}\n\n/** Item of a breadcrumb. */\nexport interface BreadcrumbItem {\n path: AbsolutePath;\n label: ReactNode;\n}\n\n/** Actions of the form app. */\nexport interface FormAppActions {\n setIssuesPanelPath: (path: AbsolutePath | null) => void;\n focus: (path: string | Path) => void;\n resetFocus: () => void;\n registerController: (\n path: AbsolutePath,\n controller?: Controller<any> | null,\n ) => (() => void) | void;\n isRegistered: (path: AbsolutePath) => boolean;\n setLatestInteraction: (path: AbsolutePath) => void;\n registerIssueMessages: (\n basePath: AbsolutePath,\n issueMessages?: Record<string, IssueMessagesByCode>,\n priority?: number,\n ) => (() => void) | void;\n getRegisteredIssueMessage: (\n path: AbsolutePath,\n code: string,\n ) => IssueMessageValue | null;\n registerLabel: (\n path: AbsolutePath,\n label: ReactNode,\n priority?: number,\n ) => (() => void) | void;\n getRegisteredLabel: (path: AbsolutePath) => ReactNode;\n getActiveIssuesPanelBreadcrumb: () => BreadcrumbItem[] | null;\n startIssuesNavigation: (options?: {\n validate?: boolean;\n setTouched?: boolean;\n }) => PromiseLike<void>;\n}\n\n/** Form app store. */\nexport type FormAppStore<T> = ReturnType<\n typeof useCreateFormAppContext<T>\n>[\"store\"];\n\n/** Form app context. */\nexport const FormAppContext = createContext<FormAppContextValue | null>(null);\n\n/** Options used to create the data table context value. */\nexport interface UseCreateFormAppContextOptions<T>\n extends Omit<FormAppContextValue<T>, \"store\"> {\n controller: Controller<T>;\n onPathFocus?: (path: AbsolutePath) => void;\n}\n\n/** Hook which creates the form app context. */\nexport function useCreateFormAppContext<T>({\n formTitle,\n controller,\n disabled,\n readOnly,\n issuesDisplayMode,\n displayIssueCodes,\n formAppElement,\n onPathFocus,\n}: UseCreateFormAppContextOptions<T>) {\n const latest = useLatestValues({ printing: usePrinting(), onPathFocus });\n\n const store = useConstant(() =>\n createStore<FormAppState<T>>()(\n subscribeWithSelector((set, get) => ({\n controller,\n focusedPath: null,\n focusCounter: 0,\n issuesPanelPath: null,\n topBarHeight: 0,\n leftSidebarWidth: 0,\n bottomPanelHeight: 0,\n startIssuesNavigation: undefined,\n latestInteraction: AbsolutePath.ROOT,\n registeredControllers: [new PathMultimap()],\n registeredIssueMessages: [new PathMultimap()],\n deferredIssueMessageRemovalEntryIds: [],\n registeredLabels: [new PathMultimap()],\n deferredLabelRemovalEntryIds: [],\n actions: {\n setIssuesPanelPath: (path: AbsolutePath | null) => {\n if (latest.printing) {\n return;\n }\n\n // Remove entries whose removal was deferred\n const {\n deferredIssueMessageRemovalEntryIds,\n deferredLabelRemovalEntryIds,\n } = get();\n if (deferredIssueMessageRemovalEntryIds.length > 0) {\n const [registeredIssueMessages] = get().registeredIssueMessages;\n for (const entryId of deferredIssueMessageRemovalEntryIds) {\n registeredIssueMessages.removeEntry(entryId);\n }\n set({ registeredIssueMessages: [registeredIssueMessages] });\n }\n if (deferredLabelRemovalEntryIds.length > 0) {\n const [registeredLabels] = get().registeredLabels;\n for (const entryId of deferredLabelRemovalEntryIds) {\n registeredLabels.removeEntry(entryId);\n }\n set({ registeredLabels: [registeredLabels] });\n }\n\n set({ issuesPanelPath: path });\n },\n getActiveIssuesPanelBreadcrumb: () => {\n const { issuesPanelPath, actions } = get();\n if (issuesPanelPath === null) {\n return null;\n }\n const breadcrumbParts: BreadcrumbItem[] = [];\n for (let i = 0; i <= issuesPanelPath.size; ++i) {\n const path =\n i === 0\n ? AbsolutePath.ROOT\n : i === issuesPanelPath.size\n ? issuesPanelPath\n : new AbsolutePath(issuesPanelPath.fragments.slice(0, i));\n const breadcrumb = actions.getRegisteredLabel(path);\n // if (!breadcrumb && process.env.NODE_ENV !== \"production\") {\n // warnOnce(`No label registered for path '${path.toString()}'.`);\n // }\n breadcrumbParts.push({\n path,\n label:\n breadcrumb ??\n (\n issuesPanelPath.fragment(\n i - 1,\n ) as AbsolutePathFragment.Id | null\n )?.id,\n });\n }\n return breadcrumbParts;\n },\n focus: (path: string | Path) => {\n if (latest.printing) {\n return;\n }\n\n const { focusedPath } = get();\n const absolutePath =\n path instanceof AbsolutePath ? path : new AbsolutePath(path);\n // Refuse non-existent paths\n if (\n !get().controller.getState().formManager.isValidPath(absolutePath)\n ) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Path to focus must only contain ids.\");\n }\n\n const focusPathChanged = !equals(focusedPath, absolutePath);\n set(({ focusedPath, focusCounter }) => ({\n focusedPath: focusPathChanged ? absolutePath : focusedPath,\n focusCounter: focusCounter + 1,\n }));\n if (focusPathChanged) {\n latest.onPathFocus?.(absolutePath);\n }\n },\n resetFocus: () => {\n if (!latest.printing) {\n set({ focusedPath: null });\n }\n },\n registerController: (\n path: AbsolutePath,\n controller?: Controller | null,\n ) => {\n if (controller == null) {\n return;\n }\n\n const [registeredControllers] = get().registeredControllers;\n const addedEntry = registeredControllers.put(path, controller);\n set(() => ({ registeredControllers: [registeredControllers] }));\n\n return () => {\n registeredControllers.removeEntry(addedEntry);\n set(() => ({ registeredControllers: [registeredControllers] }));\n };\n },\n isRegistered: (path: AbsolutePath) =>\n get().registeredControllers[0].containsPath(path),\n setLatestInteraction: (path: AbsolutePath) => {\n if (!latest.printing) {\n set({ latestInteraction: path });\n }\n },\n registerIssueMessages: (\n basePath: AbsolutePath,\n issueMessages?: Record<string, IssueMessagesByCode>,\n priority = 0,\n ) => {\n if (issueMessages == null) {\n return;\n }\n\n const [registeredIssueMessages] = get().registeredIssueMessages;\n const addedEntryIds: PathMultimapEntryId[] = [];\n for (const [path, issueMessagesByCode] of Object.entries(\n issueMessages,\n )) {\n addedEntryIds.push(\n registeredIssueMessages.put(basePath.resolve(path), {\n messages: issueMessagesByCode,\n priority,\n }),\n );\n }\n set(() => ({\n registeredIssueMessages: [registeredIssueMessages],\n }));\n\n return () => {\n const { issuesPanelPath } = get();\n for (const entryId of addedEntryIds) {\n // If the message being unregistered is currently in use by the\n // issues panel, defer its removal\n if (\n issuesPanelPath &&\n registeredIssueMessages\n .getEntry(entryId)!\n .path.append(AbsolutePathFragment.RecursiveWildcard)\n .contains(issuesPanelPath)\n ) {\n get().deferredIssueMessageRemovalEntryIds.push(entryId);\n } else {\n registeredIssueMessages.removeEntry(entryId);\n }\n }\n set(() => ({\n registeredIssueMessages: [registeredIssueMessages],\n }));\n };\n },\n getRegisteredIssueMessage: (path: AbsolutePath, code: string) => {\n const [registeredIssueMessages] = get().registeredIssueMessages;\n\n // Find the match with the most specific path\n let bestMatch = null;\n for (const entry of registeredIssueMessages.entries(path)) {\n if (entry.value.messages[code] == null) {\n continue;\n }\n\n const diff =\n bestMatch &&\n comparePathsBySpecificity(bestMatch.path, entry.path);\n if (\n bestMatch == null ||\n diff! < 0 ||\n // Larger priority wins\n (diff === 0 &&\n entry.value.priority > bestMatch.value.priority) ||\n // Last inserted wins\n (diff === 0 &&\n entry.value.priority === bestMatch.value.priority &&\n entry.id > bestMatch.id)\n ) {\n bestMatch = entry;\n }\n }\n return bestMatch?.value.messages[code] ?? null;\n },\n registerLabel: (\n path: AbsolutePath,\n label: ReactNode,\n priority = 0,\n ) => {\n if (!label) {\n return;\n }\n\n const [registeredLabels] = get().registeredLabels;\n const addedEntry = registeredLabels.put(path, { label, priority });\n set(() => ({ registeredLabels: [registeredLabels] }));\n\n return () => {\n const { issuesPanelPath } = get();\n // If the label being unregistered is currently in use by the\n // issues panel, defer its removal\n if (\n issuesPanelPath &&\n registeredLabels\n .getEntry(addedEntry)!\n .path.append(AbsolutePathFragment.RecursiveWildcard)\n .contains(issuesPanelPath)\n ) {\n get().deferredLabelRemovalEntryIds.push(addedEntry);\n } else {\n registeredLabels.removeEntry(addedEntry);\n }\n set(() => ({ registeredLabels: [registeredLabels] }));\n };\n },\n getRegisteredLabel: (path: AbsolutePath) => {\n const [registeredLabels] = get().registeredLabels;\n\n // Find the match with the most specific path\n let bestMatch = null;\n for (const entry of registeredLabels.entries(path)) {\n const diff =\n bestMatch &&\n comparePathsBySpecificity(bestMatch.path, entry.path);\n if (\n bestMatch == null ||\n diff! < 0 ||\n // Larger priority wins\n (diff === 0 &&\n entry.value.priority > bestMatch.value.priority) ||\n // Last inserted wins\n (diff === 0 &&\n entry.value.priority === bestMatch.value.priority &&\n entry.id > bestMatch.id)\n ) {\n bestMatch = entry;\n }\n }\n return bestMatch?.value.label ?? null;\n },\n startIssuesNavigation: async ({\n validate = true,\n setTouched = validate,\n } = {}) => {\n const formManager = get().controller.getState().formManager;\n if (setTouched) {\n await formManager.setTouched();\n }\n if (validate && formManager.autoValidationStatus === \"inactive\") {\n await formManager.validate();\n }\n get().startIssuesNavigation?.();\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.setState({ controller });\n }, [controller, store]);\n\n return useMemo(\n () => ({\n formTitle,\n disabled,\n readOnly,\n issuesDisplayMode,\n displayIssueCodes,\n formAppElement,\n store,\n }),\n [\n disabled,\n displayIssueCodes,\n formAppElement,\n formTitle,\n issuesDisplayMode,\n readOnly,\n store,\n ],\n );\n}\n\n/** Returns the context of the form app. */\nexport function useFormAppContext<T = unknown>(): FormAppContextValue<T> {\n const formAppContext = useContext(FormAppContext);\n if (!formAppContext) {\n throw new Error(\"Form app context not in scope.\");\n }\n return formAppContext as FormAppContextValue<T>;\n}\n\n/** Returns the title of the form, if provided to the `FormApp` component. */\nexport function useFormTitle(): string | undefined {\n return useFormAppContext().formTitle;\n}\n\n/** Returns a boolean representing whether the form is disabled. */\nexport function useFormIsDisabled(): boolean {\n return useFormAppContext().disabled;\n}\n\n/** Returns a boolean representing whether the form is read-only. */\nexport function useFormIsReadOnly(): boolean {\n return useFormAppContext().readOnly;\n}\n\n/** Returns the form app's display mode for issue messages. */\nexport function useIssuesDisplayMode(): IssuesDisplayMode {\n return useFormAppContext().issuesDisplayMode;\n}\n\n/**\n * Returns whether issue codes should be displayed (by default) within issue\n * messages.\n */\nexport function useDisplayIssueCodesInIssueMessages(): boolean {\n return useFormAppContext().displayIssueCodes;\n}\n\n/** Hook providing access to the form app's HTML form element. */\nexport function useFormAppElement(): HTMLFormElement {\n return useFormAppContext().formAppElement!;\n}\n\n/**\n * Hook exposing a function that can be used to specify the height of the form\n * app's top bar.\n */\nexport function useSetTopBarHeight(): (height?: number) => void {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n return useCallback(\n (height?: number) =>\n !printing && store.setState({ topBarHeight: height ?? 0 }),\n [printing, store],\n );\n}\n\n/**\n * Hook exposing a function that can be used to specify the width of the form\n * app's left panel.\n */\nexport function useSetLeftSidebarWidth(): (width?: number) => void {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n return useCallback(\n (width?: number) =>\n !printing && store.setState({ leftSidebarWidth: width ?? 0 }),\n [printing, store],\n );\n}\n\n/**\n * Hook exposing a function that can be used to specify the height of the form\n * app's bottom panel.\n */\nexport function useSetBottomPanelHeight(): (height?: number) => void {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n return useCallback(\n (height?: number) =>\n !printing && store.setState({ bottomPanelHeight: height ?? 0 }),\n [printing, store],\n );\n}\n\n/**\n * Returns the current issues panel path of the form app and a function that can\n * be used to set it, ala `useState`.\n */\nexport function useIssuesPanelPath(): [\n AbsolutePath | null,\n FormAppActions[\"setIssuesPanelPath\"],\n] {\n return useStore(\n useFormAppContext().store,\n useShallow((state) => [\n state.issuesPanelPath,\n state.actions.setIssuesPanelPath,\n ]),\n );\n}\n\n/** Hook exposing a function that can be used to focus a path within a form app. */\nexport function useFocus(): FormAppActions[\"focus\"] {\n return useStore(useFormAppContext().store, (state) => state.actions.focus);\n}\n\n/** Hook exposing a function that can be used to reset the focus. */\nexport function useResetFocus(): FormAppActions[\"resetFocus\"] {\n return useStore(\n useFormAppContext().store,\n (state) => state.actions.resetFocus,\n );\n}\n\n/**\n * Hook used to register a controller within the form app. This makes the form\n * app aware that a controller of a certain path is currently being rendered.\n */\nexport function useRegisterController(controller: Controller<any>) {\n const store = useFormAppContext().store;\n const path = controller.usePath();\n const printing = usePrinting();\n useEffect(() => {\n if (!printing) {\n return store.getState().actions.registerController(path, controller);\n }\n }, [store, controller, path, printing]);\n}\n\n/** Hook to check whether there is a registered controller for the provided path. */\nexport function useIsRegistered(path?: AbsolutePath | null): boolean {\n return useStore(\n useFormAppContext().store,\n (state) => path != null && state.actions.isRegistered(path),\n );\n}\n\n/** Hook exposing the latest path that the user has interacted with. */\nexport function useLatestInteraction(): AbsolutePath {\n return useStore(\n useFormAppContext().store,\n (state) => state.latestInteraction,\n );\n}\n\n/** Hook exposing a function to set the latest path the user has interacted with. */\nexport function useSetLatestInteraction(): FormAppActions[\"setLatestInteraction\"] {\n return useStore(\n useFormAppContext().store,\n (state) => state.actions.setLatestInteraction,\n );\n}\n\n/** Hook used to register issue messages within the form app. */\nexport function useRegisterIssueMessages(\n path: AbsolutePath | null | undefined,\n issueMessages?: Record<string, IssueMessagesByCode>,\n priority?: number,\n) {\n const store = useFormAppContext().store;\n const printing = usePrinting();\n useEffect(() => {\n if (!printing && path != null) {\n return store\n .getState()\n .actions.registerIssueMessages(path, issueMessages, priority);\n }\n }, [path, issueMessages, priority, store, printing]);\n}\n\n/** Hook used to get the issue message value for the provided path and code. */\nexport function useRegisteredIssueMessage(\n path: AbsolutePath | null | undefined,\n code: string,\n): IssueMessageValue | null {\n return useStore(useFormAppContext().store, (state) =>\n path == null ? null : state.actions.getRegisteredIssueMessage(path, code),\n );\n}\n\n/** Hook used to register a label within the form app. */\nexport function useRegisterLabel(\n path: AbsolutePath | null | undefined,\n label: ReactNode,\n priority = 0,\n) {\n const store = useFormAppContext().store;\n const printing = usePrinting();\n useEffect(() => {\n if (!printing && path != null) {\n return store.getState().actions.registerLabel(path, label, priority);\n }\n }, [store, path, label, priority, printing]);\n}\n\n/**\n * Hook used to get the label parts associated with the active issues panel\n * path.\n */\nexport function useActiveIssuesPanelBreadcrumb(): BreadcrumbItem[] | null {\n return useStore(\n useFormAppContext().store,\n useEqualityFn(\n (state) => state.actions.getActiveIssuesPanelBreadcrumb(),\n equalBreadcrumbItems,\n ),\n );\n}\nfunction equalBreadcrumbItems(\n breadcrumbs1: BreadcrumbItem[] | null,\n breadcrumbs2: BreadcrumbItem[] | null,\n) {\n if (breadcrumbs1 == null || breadcrumbs2 == null) {\n return breadcrumbs1 === breadcrumbs2;\n }\n return (\n breadcrumbs1.length === breadcrumbs2.length &&\n breadcrumbs1.every((breadcrumb1, i) => {\n const breadcrumb2 = breadcrumbs2[i];\n return (\n breadcrumb1.path.toString() === breadcrumb2.path.toString() &&\n Object.is(breadcrumb1.label, breadcrumb2.label)\n );\n })\n );\n}\n\n/**\n * Hook exposing a function that can be used to start navigating through the\n * form app's issues.\n */\nexport function useStartIssuesNavigation(): FormAppActions[\"startIssuesNavigation\"] {\n return useStore(\n useFormAppContext().store,\n (state) => state.actions.startIssuesNavigation,\n );\n}\n\n/** Options available to the {@link useOnPathFocus} hook. */\nexport interface UseOnFocusedPathChangeOptions {\n /**\n * Whether to run the callback immediately with the current focused path.\n *\n * @default true\n */\n fireImmediately?: boolean;\n}\n\n/**\n * Hook used to run a given function whenever the form app's focused path\n * changes.\n *\n * @param cb Function to run when the focused path changes. This function should\n * hopefully not change on every render (i.e., it should be memoised via\n * `useCallback` or be defined externally).\n * @param options Hook options.\n */\nexport function useOnPathFocus(\n cb: (focusedPath: AbsolutePath) => void,\n { fireImmediately = true }: UseOnFocusedPathChangeOptions = {},\n) {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n useEffect(() => {\n if (!printing) {\n return store.subscribe(\n ({ focusedPath, focusCounter }) => ({ focusedPath, focusCounter }),\n ({ focusedPath }) => focusedPath && cb(focusedPath),\n { fireImmediately, equalityFn: shallow },\n );\n }\n }, [cb, fireImmediately, printing, store]);\n}\n\n/** Hook used to set the function which starts issue navigation. */\nexport function useSetStartIssuesNavigation(fn: () => void) {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n useEffect(() => {\n if (!printing) {\n store.setState({ startIssuesNavigation: fn });\n return () => store.setState({ startIssuesNavigation: undefined });\n }\n }, [fn, printing, store]);\n}\n","import type { Controller } from \"@ostack.tech/kform-react\";\nimport { NATIVE_CONTROLS, useCssVars, useSpacing } from \"@ostack.tech/ui\";\nimport { type RefObject, useCallback, useRef } from \"react\";\n\nimport { useOnPathFocus } from \"../components/FormApp\";\nimport { useResetFocus } from \"../components/FormApp/FormAppContext.ts\";\nimport { usePrefix } from \"../providers/PrefixSuffixProvider\";\n\nconst FOCUSABLE_ELEMENTS = [\"INPUT\", \"SELECT\", \"TEXTAREA\"];\n\n/**\n * Function used to scroll an element into view.\n *\n * @param el Element to scroll into view.\n * @param options Scroll into view options.\n */\nexport type ScrollIntoViewFn = (\n el: HTMLElement,\n options?: ScrollIntoViewOptions,\n) => void;\n\n/**\n * Hook used to autofocus a control when the active path changes, given the\n * control's path.\n *\n * @param controller Control's controller.\n * @param enabled Whether to enable the auto-focus behaviour.\n * @returns Reference that should be set on the focusable element of the\n * control.\n */\nexport function useControlAutofocus<\n T = unknown,\n TElem extends HTMLElement = HTMLElement,\n>(\n { usePath, useExists }: Controller<T>,\n enabled = true,\n): RefObject<TElem | null> {\n const controlRef = useRef<TElem | null>(null);\n const path = usePath();\n const exists = useExists();\n const resetFocus = useResetFocus();\n const scrollIntoView = useScrollIntoView();\n\n const timeoutId = useRef<number>(undefined);\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const control = controlRef.current;\n if (enabled && control && exists && path.equals(focusedPath)) {\n clearTimeout(timeoutId.current);\n timeoutId.current = window.setTimeout(() => {\n scrollIntoView(control);\n visiblyFocus(control);\n resetFocus();\n }, 50);\n }\n },\n [enabled, exists, path, resetFocus, scrollIntoView],\n ),\n );\n\n return controlRef;\n}\n\n/**\n * Visibly focuses the provided element.\n *\n * @param el Element to visibly focus.\n * @param options Focus options.\n */\nexport function visiblyFocus(el: HTMLElement, options?: FocusOptions) {\n const focusOptions: FocusOptions = {\n preventScroll: true,\n // This option is experimental, but works well in Firefox, so might as well\n // use it\n focusVisible: true,\n ...options,\n } as any;\n\n if (FOCUSABLE_ELEMENTS.includes(el.tagName)) {\n el.focus(focusOptions);\n } else {\n // XXX: Trick browser into triggering `:focus-visible`\n const contentEditable = el.contentEditable;\n el.contentEditable = \"true\";\n el.focus(focusOptions);\n el.contentEditable = contentEditable;\n }\n}\n\n/**\n * Returns a function used the scroll an element into view, taking into account\n * the form app's sticky elements, so that elements don't end up hidden behind\n * them.\n */\nexport function useScrollIntoView(): ScrollIntoViewFn {\n const prefix = usePrefix();\n const spacing = useSpacing();\n const { cssVar } = useCssVars({ prefix });\n\n return useCallback(\n (el: HTMLElement, options?: ScrollIntoViewOptions) => {\n const scrollableParent = getScrollableParent(el);\n const scrollMarginBlockStart = el.style.scrollMarginBlockStart;\n const scrollMarginBlockEnd = el.style.scrollMarginBlockEnd;\n el.style.scrollMarginBlockStart = `calc(${cssVar(\"top-bar-height\")} + ${cssVar(\n \"form-pages-page-header-height\",\n )} + ${spacing(4)})`;\n el.style.scrollMarginBlockEnd = `calc(${cssVar(\"bottom-panel-height\")} + ${spacing(4)})`;\n const shouldCenter =\n !NATIVE_CONTROLS.has(el.tagName) ||\n scrollableParent !==\n (document.scrollingElement ?? document.documentElement);\n el.scrollIntoView({\n block: shouldCenter ? \"center\" : \"nearest\",\n inline: shouldCenter ? \"center\" : \"nearest\",\n behavior: \"smooth\",\n ...options,\n });\n el.style.scrollMarginBlockStart = scrollMarginBlockStart;\n el.style.scrollMarginBlockEnd = scrollMarginBlockEnd;\n },\n [cssVar, spacing],\n );\n}\n\n/**\n * Gets the nearest scrollable parent.\n *\n * @param el Element for which to get the nearest scrollable parent.\n */\nfunction getScrollableParent(el: Element): Element {\n let current = el.parentNode;\n while (current instanceof Element) {\n const overflow = getComputedStyle(current, null).getPropertyValue(\n \"overflow\",\n );\n if (overflow.includes(\"scroll\") || overflow.includes(\"auto\")) {\n return current;\n }\n current = current.parentNode;\n }\n return document.scrollingElement ?? document.documentElement;\n}\n","import { useFormController } from \"@ostack.tech/kform-react\";\nimport { useCallback } from \"react\";\n\nimport {\n useScrollIntoView,\n visiblyFocus,\n} from \"../../utils/useControlAutofocus.ts\";\nimport {\n useFormAppElement,\n useIssuesDisplayMode,\n useOnPathFocus,\n useResetFocus,\n} from \"./FormAppContext.ts\";\n\n/** Component enabling support for auto-focusing the form app via `focus(\"/\")`. */\nexport function FormAppAutoFocus() {\n const initialized = useFormController().useInitialized();\n const formAppEl = useFormAppElement();\n const scrollIntoView = useScrollIntoView();\n\n const issuesDisplayMode = useIssuesDisplayMode();\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n if (initialized && focusedPath.isRoot) {\n // In inline mode an issues popover should get focused instead\n if (issuesDisplayMode === \"panel\") {\n scrollIntoView(formAppEl);\n visiblyFocus(formAppEl);\n }\n resetFocus();\n }\n },\n [initialized, issuesDisplayMode, resetFocus, scrollIntoView, formAppEl],\n ),\n );\n return null;\n}\n","import {\n cx,\n useCombinedRef,\n useCssVars,\n useResponsiveValues,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type Dispatch,\n forwardRef,\n type SetStateAction,\n useEffect,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport type { FormAppProps } from \"./FormApp.tsx\";\nimport { useFormAppContext } from \"./FormAppContext.ts\";\n\n/** Properties of the form application element component. */\nexport interface FormAppElementProps\n extends Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"onReset\">,\n Pick<FormAppProps, \"minHeight\"> {\n formAppElement: HTMLFormElement | null;\n setFormAppElement: Dispatch<SetStateAction<HTMLFormElement | null>>;\n}\n\n/** Form application element. */\nexport const FormAppElement = forwardRef<\n ComponentRef<\"form\">,\n FormAppElementProps\n>(function FormAppElement(\n {\n formAppElement,\n setFormAppElement,\n minHeight,\n className,\n style,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { cssVarName } = useCssVars({ prefix });\n const { responsiveValueToCssVarsAndDataAttrs } = useResponsiveValues({\n prefix,\n });\n const { store } = useFormAppContext();\n\n // Top-bar height\n useEffect(\n () =>\n store.subscribe(\n (state) => state.topBarHeight,\n (height) =>\n formAppElement?.style.setProperty(\n cssVarName(\"top-bar-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, formAppElement, store],\n );\n\n // Left sidebar width\n useEffect(\n () =>\n store.subscribe(\n (state) => state.leftSidebarWidth,\n (width) =>\n formAppElement?.style.setProperty(\n cssVarName(\"left-sidebar-width\"),\n `${width}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, formAppElement, store],\n );\n\n // Bottom panel height\n useEffect(\n () =>\n store.subscribe(\n (state) => state.bottomPanelHeight,\n (height) =>\n formAppElement?.style.setProperty(\n cssVarName(\"bottom-panel-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, formAppElement, store],\n );\n\n // Form app min height\n const { cssVars, dataAttrs } = responsiveValueToCssVarsAndDataAttrs(\n \"form-app\",\n \"min-height\",\n minHeight,\n (v) => (typeof v === \"number\" ? `${v}px` : v),\n );\n\n const combinedFormAppRef = useCombinedRef(setFormAppElement, forwardedRef);\n return (\n <form\n className={cx(prefix(\"form-app\"), className)}\n style={{ ...cssVars, ...style }}\n tabIndex={0}\n {...dataAttrs}\n {...otherProps}\n ref={combinedFormAppRef}\n >\n {children}\n </form>\n );\n});\n","import type { Path } from \"@ostack.tech/kform\";\nimport { useResolvedPath } from \"@ostack.tech/kform-react\";\nimport type { ReactNode } from \"react\";\n\nimport type { IssueMessagesByCode } from \"../IssueMessages\";\nimport { useRegisterIssueMessages } from \"./FormAppContext.ts\";\n\n/** Properties of the form app issue messages component. */\nexport interface FormAppIssueMessagesProps {\n /** Base path for the paths used in `messages`. */\n path?: string | Path;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their code).\n *\n * Provided paths may contain wildcards, which will have a lower priority when\n * matched against.\n *\n * These messages are used by the `IssueMessages` and `IssuesPanel`\n * components.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"/**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"/my/field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /**\n * Priority to use when registering issue messages.\n *\n * When multiple issue messages are associated with the same path, then the\n * one registered with the highest priority \"wins\".\n *\n * @default 0\n */\n priority?: number;\n children: ReactNode;\n}\n\n/** Component used to register new issue messages within the form app. */\nexport function FormAppIssueMessages({\n path,\n issueMessages,\n priority,\n children,\n}: FormAppIssueMessagesProps) {\n const absolutePath = useResolvedPath(path);\n useRegisterIssueMessages(absolutePath, issueMessages, priority);\n return children;\n}\n","import {\n AbsolutePath,\n type Path,\n type Schema,\n type SchemaKt,\n} from \"@ostack.tech/kform\";\nimport {\n type Controller,\n FormContext,\n type FormOptions,\n useForm,\n} from \"@ostack.tech/kform-react\";\nimport {\n PrefixProvider,\n type Responsive,\n Root,\n useIsInRoot,\n usePrintInProgress,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport {\n ActivePathProvider,\n type OnActivePathChangeNavigationOptions,\n} from \"../../providers/ActivePathProvider\";\nimport type { LocalizationObject } from \"../../providers/LocalizationProvider\";\nimport {\n LocalizationContext,\n LocalizationProvider,\n} from \"../../providers/LocalizationProvider\";\nimport { PrefixSuffixProvider } from \"../../providers/PrefixSuffixProvider\";\nimport type { IssueMessagesByCode } from \"../IssueMessages\";\nimport { FormAppAutoFocus } from \"./FormAppAutoFocus.tsx\";\nimport { FormAppContext, useCreateFormAppContext } from \"./FormAppContext.ts\";\nimport { FormAppElement } from \"./FormAppElement.tsx\";\nimport { FormAppIssueMessages } from \"./FormAppIssueMessages.tsx\";\n\n/** Mode of displaying issue messages. */\nexport type IssuesDisplayMode = \"inline\" | \"panel\";\n\n/** Properties of the form app component. */\nexport type FormAppProps<T = any> = Pick<\n ComponentPropsWithoutRef<typeof Root>,\n | \"enableErrorReporting\"\n | \"reportError\"\n | \"errorReportingUrl\"\n | \"errorReportingMethod\"\n | \"encodeErrorReport\"\n | \"encodedErrorReportMimeType\"\n | \"errorReportingOptions\"\n | \"baseDocumentTitle\"\n | \"documentTitleBaseSeparator\"\n | \"documentTitleBreadcrumbsSeparator\"\n | \"portalsContainer\"\n | \"tooltipsDelayDuration\"\n | \"tooltipsSkipDelayDuration\"\n | \"disableTooltipsHoverableContent\"\n | \"toastsLabel\"\n | \"toastsDuration\"\n | \"toastsSwipeDirection\"\n | \"toastsSwipeThreshold\"\n | \"toastViewportHotkey\"\n | \"toastViewportLabel\"\n | \"toastViewportProps\"\n | \"errorBoundaryProps\"\n> &\n FormOptions<T> &\n Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"onReset\"> & {\n /** Schema of the form. */\n schema: Schema<T> | SchemaKt;\n /** Title of the form. */\n formTitle?: string;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * the form app. Defaults to the `formTitle`.\n */\n issuesPanelLabel?: ReactNode;\n /** Whether to disable the whole form. */\n disabled?: boolean;\n /** Whether to set the whole form as read-only. */\n readOnly?: boolean;\n /**\n * Custom suffix to add to the ostack/UI's prefix when prefixing all\n * component classes, styles, _etc._\n *\n * This prefix-suffix should match the `$prefix-suffix` SCSS variable.\n */\n prefixSuffix?: string;\n /** Uncontrolled form app locale. */\n defaultLocale?: LocalizationObject;\n /** Controlled form app locale. */\n locale?: LocalizationObject;\n /**\n * Function called when the locale changes.\n *\n * @param locale New locale.\n */\n onLocaleChange?: (locale: LocalizationObject) => void;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their\n * code).\n *\n * Provided paths may contain wildcards, which will have a lower priority\n * when matched against.\n *\n * These messages are used by the `IssueMessages` component.\n *\n * **Note:** Changes to `issueMessages` are handled correctly, but are not\n * efficient. Please make sure that the identity of the provided value\n * doesn't change at every render.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"/**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"/my/field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /**\n * Mode of displaying issues:\n *\n * - `inline` mode dispays issue messages near the component containing the\n * issues. In this mode the bottom issues panel only functions as an aid\n * for navigating issues.\n * - `panel` mode displays issue messages within the bottom issues panel.\n *\n * @default inline\n */\n issuesDisplayMode?: IssuesDisplayMode;\n /**\n * Global setting which specifies whether issue codes should be added to\n * each issue message.\n *\n * @default false\n */\n displayIssueCodes?: boolean;\n /**\n * When provided, the form app's active path will be controlled by a URL\n * search parameter with the provided name.\n */\n activePathSearchParam?: string;\n /** Uncontrolled default active path to use. */\n defaultActivePath?: string | Path;\n /** Controlled active path to use. */\n activePath?: string | Path;\n /**\n * Callback called whenever the active path changes.\n *\n * @param activePath New active path.\n * @param options Navigation options to use when controlling the active path\n * via the browser's URL.\n */\n onActivePathChange?: (\n activePath: AbsolutePath,\n options: OnActivePathChangeNavigationOptions,\n ) => void;\n /**\n * Function called when a form path is focused.\n *\n * @param path Focused path.\n */\n onPathFocus?: (path: AbsolutePath) => void;\n /**\n * Minimum height of the form app. Values should **not** be percentages.\n *\n * @default \"100dvh\"\n */\n minHeight?: Responsive<number | string>;\n /** Reference to the form app's API. */\n apiRef?: Ref<FormAppApi<T> | undefined>;\n };\n\n/** Imperative form app API. */\nexport type FormAppApi<T = unknown> = Controller<T> & {\n /**\n * Focuses the form element at the provided path.\n *\n * @param path Path of element to focus.\n */\n focus: (path: string | Path) => void;\n /**\n * Starts issues navigation (when an `IssuesPanel` component exists within).\n *\n * @param options Options used when starting issues validation.\n */\n startIssuesNavigation: (options: {\n validate?: boolean;\n setTouched?: boolean;\n }) => PromiseLike<void>;\n};\n\n/**\n * Root component of a form application.\n *\n * This component automatically renders the ostack/UI's `Root` component when\n * not rendered inside of one, in which case it accepts properties that would\n * otherwise be passed to the ostack/UI `Root` component. In this scenario, the\n * ostack/UI's `locale` is automatically provided to the ostack/UI `Root`\n * component from the provided `FormApp` `locale`.\n */\nexport const FormApp = forwardRef(function FormApp<T = unknown>(\n {\n enableErrorReporting,\n reportError,\n errorReportingUrl,\n errorReportingMethod,\n encodeErrorReport,\n encodedErrorReportMimeType,\n errorReportingOptions,\n baseDocumentTitle,\n documentTitleBaseSeparator,\n documentTitleBreadcrumbsSeparator,\n portalsContainer,\n tooltipsDelayDuration,\n tooltipsSkipDelayDuration,\n disableTooltipsHoverableContent,\n toastsLabel,\n toastsDuration,\n toastsSwipeDirection,\n toastsSwipeThreshold,\n toastViewportHotkey,\n toastViewportLabel,\n toastViewportProps,\n errorBoundaryProps,\n schema,\n initialValue,\n formTitle,\n issuesPanelLabel,\n disabled = false,\n readOnly = false,\n prefix: newPrefix,\n prefixSuffix,\n defaultLocale,\n locale: controlledLocale,\n onLocaleChange,\n issueMessages,\n issuesDisplayMode = \"inline\",\n displayIssueCodes = false,\n // activePathSearchParam,\n defaultActivePath,\n activePath,\n onActivePathChange,\n onPathFocus,\n minHeight,\n apiRef,\n externalContexts,\n validationMode = readOnly ? \"manual\" : \"auto\",\n confirmUnloadWhenDirty,\n confirmUnloadMessage,\n onSubmit,\n onInvalidSubmit,\n onSuccessfulSubmit,\n onFailedSubmit,\n validateOnSubmit,\n setTouchedOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n onReset,\n onInitialized,\n onUninitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n ...otherProps\n }: FormAppProps,\n forwardedRef: ForwardedRef<ComponentRef<\"form\">>,\n) {\n const isInRoot = useIsInRoot();\n const rootProps = {\n enableErrorReporting,\n reportError,\n errorReportingUrl,\n errorReportingMethod,\n encodeErrorReport,\n encodedErrorReportMimeType,\n errorReportingOptions,\n baseDocumentTitle,\n documentTitleBaseSeparator,\n documentTitleBreadcrumbsSeparator,\n portalsContainer,\n tooltipsDelayDuration,\n tooltipsSkipDelayDuration,\n disableTooltipsHoverableContent,\n toastsLabel,\n toastsDuration,\n toastsSwipeDirection,\n toastsSwipeThreshold,\n toastViewportHotkey,\n toastViewportLabel,\n toastViewportProps,\n errorBoundaryProps,\n };\n if (isInRoot && Object.values(rootProps).some((prop) => prop !== undefined)) {\n warnOnce(\n `FormApp: Properties ${Object.keys(rootProps)\n .map((prop) => `\\`${prop}\\``)\n .join(\", \")} have no effect when the \\`FormApp\\` is already ` +\n \"inside an ostack/UI's `Root` component. Please set any of these \" +\n \"properties on the `Root` component directly instead.\",\n );\n }\n\n const contextLocale = useContext(LocalizationContext)?.locale;\n const locale = controlledLocale ?? defaultLocale ?? contextLocale;\n if (locale == null) {\n throw new Error(\n \"FormApp: No locale has been provided. Either provide a \" +\n \"`defaultLocale`/`locale` property or wrap the component in a \" +\n \"`LocalizationProvider`.\",\n );\n }\n formTitle ??= locale.FormApp.formTitle;\n issuesPanelLabel ??= locale.FormApp.issuesPanelLabel ?? formTitle;\n confirmUnloadMessage ??= locale.FormApp.confirmUnloadMessage;\n\n const controller = useForm<T>(schema, {\n initialValue,\n externalContexts,\n validationMode,\n confirmUnloadWhenDirty,\n confirmUnloadMessage,\n onSubmit,\n onInvalidSubmit,\n onSuccessfulSubmit,\n onFailedSubmit,\n validateOnSubmit,\n setTouchedOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n onReset,\n onInitialized,\n onUninitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n } as FormOptions<T>);\n const { formProps } = controller;\n\n // Reference to the form app element (used to scroll into view on page\n // changes, since scrolling a page itself into view hides elements under the\n // top-bar)\n const [formAppElement, setFormAppElement] = useState<HTMLFormElement | null>(\n null,\n );\n\n const formManager = controller.useFormManager();\n const formContext = useMemo(\n () => ({\n formManager,\n currentPath: AbsolutePath.ROOT,\n controller,\n }),\n [controller, formManager],\n );\n\n const printInProgress = usePrintInProgress();\n const displayDisabled =\n controller.useSubmitting() || disabled || printInProgress;\n const formAppContextValue = useCreateFormAppContext<T>({\n formTitle,\n disabled: displayDisabled,\n readOnly,\n issuesDisplayMode,\n displayIssueCodes,\n controller,\n onPathFocus,\n formAppElement,\n });\n const { store } = formAppContextValue;\n\n useEffect(\n () =>\n store\n .getState()\n .actions.registerController(AbsolutePath.ROOT, controller),\n [controller, store],\n );\n\n const absolutePath = controller.usePath();\n useEffect(\n () =>\n store.getState().actions.registerLabel(absolutePath, issuesPanelLabel),\n [absolutePath, issuesPanelLabel, store],\n );\n\n // Expose the control's API via `apiRef`\n const { focus, startIssuesNavigation } = useStore(\n store,\n (state) => state.actions,\n );\n useImperativeHandle(\n apiRef,\n () => ({\n ...controller,\n focus,\n startIssuesNavigation,\n }),\n [focus, controller, startIssuesNavigation],\n );\n\n const formAppEl = (\n <FormAppElement\n minHeight={minHeight}\n formAppElement={formAppElement}\n setFormAppElement={setFormAppElement}\n {...formProps}\n {...otherProps}\n ref={forwardedRef}\n />\n );\n\n return (\n <PrefixProvider prefix={newPrefix}>\n <PrefixSuffixProvider prefixSuffix={prefixSuffix}>\n <LocalizationProvider\n defaultLocale={defaultLocale}\n locale={controlledLocale}\n onLocaleChange={onLocaleChange}\n >\n <FormContext.Provider value={formContext}>\n <FormAppContext.Provider value={formAppContextValue as never}>\n <ActivePathProvider\n defaultActivePath={defaultActivePath}\n activePath={activePath}\n onActivePathChange={onActivePathChange}\n >\n <FormAppIssueMessages\n issueMessages={locale.FormApp.issueMessages}\n priority={-1}\n >\n <FormAppIssueMessages issueMessages={issueMessages}>\n <FormAppAutoFocus />\n\n {isInRoot ? (\n formAppEl\n ) : (\n <Root asChild {...rootProps}>\n {formAppEl}\n </Root>\n )}\n </FormAppIssueMessages>\n </FormAppIssueMessages>\n </ActivePathProvider>\n </FormAppContext.Provider>\n </FormContext.Provider>\n </LocalizationProvider>\n </PrefixSuffixProvider>\n </PrefixProvider>\n );\n});\n","import { type ReactNode, useMemo } from \"react\";\n\nimport { FormAppContext, useFormAppContext } from \"./FormAppContext.ts\";\n\n/** Properties of the form app status component. */\nexport interface FormAppStatusProps {\n /**\n * Whether to mark the form app as disabled for children of this component.\n *\n * This property has no effect when set to `false`.\n *\n * @default false\n */\n disabled?: boolean;\n /**\n * Whether to mark the form app as read-only for children of this component.\n *\n * This property has no effect when set to `false`.\n *\n * @default false\n */\n readOnly?: boolean;\n children: ReactNode;\n}\n\n/** Component used to apply a different form app status to part of the form. */\nexport function FormAppStatus({\n disabled = false,\n readOnly = false,\n children,\n}: FormAppStatusProps) {\n const formAppContext = useFormAppContext();\n return (\n <FormAppContext.Provider\n value={useMemo(\n () => ({\n ...formAppContext,\n disabled: formAppContext.disabled || disabled,\n readOnly: formAppContext.readOnly || readOnly,\n }),\n [disabled, formAppContext, readOnly],\n )}\n >\n {children}\n </FormAppContext.Provider>\n );\n}\n","import { AbsolutePath, AbsolutePathFragment } from \"@ostack.tech/kform\";\n\n/**\n * Function which selects the most \"specific\" path from a list of paths, given a\n * path to match. `currentActivePath` contains the path that is currently\n * active.\n *\n * The list of paths may contain paths with a single trailing wildcard.\n *\n * This function is used by the `Annexes`, `FormPages`, and `FormStepper`\n * components to select the next path that should be focused when the focused\n * path changes.\n */\nexport function mostSpecificPath(\n toMatch: AbsolutePath | null,\n paths: AbsolutePath[],\n currentActivePath: AbsolutePath | null,\n): AbsolutePath | null {\n if (!toMatch || paths.length === 0) {\n return null;\n }\n\n // Filter paths containing the focused path and pick the one with the most\n // specific (longest) path\n const mostSpecific = paths\n .filter((path) =>\n path.append(AbsolutePathFragment.RecursiveWildcard).contains(toMatch),\n )\n .reduce(\n (mostSpecific: AbsolutePath | null, path) =>\n mostSpecific === null || path.size > mostSpecific.size\n ? // Replace wildcard with the id of the path to match\n path.lastFragment === AbsolutePathFragment.Wildcard\n ? new AbsolutePath(toMatch.fragments.slice(0, path.size))\n : path\n : mostSpecific,\n null,\n );\n if (mostSpecific) {\n return mostSpecific;\n }\n\n // Return the currently active path when it is still one of the provided paths\n if (\n currentActivePath &&\n paths.some((path) => path.contains(currentActivePath))\n ) {\n return currentActivePath;\n }\n\n // Fallback to the first path\n return paths[0];\n}\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n type DisplayStatus,\n type FormManager,\n listableSize,\n type Path,\n type Schema,\n type SealedValidationIssue,\n sliceTable,\n type Table,\n type TableRowId,\n} from \"@ostack.tech/kform\";\nimport {\n computed,\n useConstant,\n useLatestValues,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { useActivePathContext } from \"../../providers/ActivePathProvider\";\nimport { mostSpecificPath } from \"../../utils/mostSpecificPath.ts\";\nimport { useOnPathFocus } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport type { AnnexesProps, AnnexObject } from \"./Annexes.tsx\";\n\n/** Value of the annexes' context. */\nexport type AnnexesContextValue = AnnexesStore;\n\n/** Resolved annex object. */\nexport interface ResolvedAnnexObject extends AnnexObject {\n path: AbsolutePath;\n}\n\n/** Annex state. */\nexport interface AnnexState {\n path: AbsolutePath;\n title: ReactNode;\n subtitle?: ReactNode;\n description?: ReactNode;\n documentTitle?: string | null;\n isRepetitive: boolean;\n schema: Schema;\n isNull: boolean;\n dirty: boolean | undefined;\n deferredDisplayStatus: DisplayStatus | undefined;\n deferredIssuesToDisplay: SealedValidationIssue[];\n}\n\n/** Repetitive annex state. */\nexport type RepetitiveAnnexState = Pick<\n ResolvedAnnexObject,\n \"path\" | \"maxAnnexes\"\n> & {\n rowIds?: TableRowId[];\n schema: Schema;\n deferredIssuesToDisplay: SealedValidationIssue[];\n};\n\n/** State of the annexes. */\nexport interface AnnexesState {\n annexes: ResolvedAnnexObject[];\n activeAnnex: AbsolutePath | null;\n nextActiveAnnex: AbsolutePath | null;\n activeAnnexIndex: () => number;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new object\n // instances\n annexStates: [Record<string, AnnexState | null>];\n repetitiveAnnexStates: [Record<string, RepetitiveAnnexState | null>];\n tabStates: () => AnnexState[];\n tablessStates: () => (AnnexState | RepetitiveAnnexState)[];\n waitingRegistration: () => AbsolutePath[];\n actions: AnnexesActions;\n}\n\n/** Actions of the annexes. */\nexport interface AnnexesActions {\n getAnnexState: (path: AbsolutePath) => AnnexState | null;\n getRepetitiveAnnexState: (path: AbsolutePath) => RepetitiveAnnexState | null;\n setAnnexes: (annexes: ResolvedAnnexObject[]) => void;\n buildAnnexStates: (\n annexes?: ResolvedAnnexObject[],\n ) => Record<string, AnnexState | null>;\n buildRepetitiveAnnexStates: (\n annexes?: ResolvedAnnexObject[],\n ) => Record<string, RepetitiveAnnexState | null>;\n setActiveAnnex: (activeAnnex: string | Path | null) => void;\n updateActiveAnnex: (oldActiveAnnexIndex: number) => void;\n registerAnnexState: (path: AbsolutePath, state: AnnexState) => void;\n registerRepetitiveAnnexState: (\n path: AbsolutePath,\n state: RepetitiveAnnexState,\n ) => void;\n addAnnex: (path: AbsolutePath, toAdd: unknown) => Promise<void>;\n removeAnnex: (path: AbsolutePath, isRepetitive: boolean) => Promise<void>;\n}\n\n/** Annexes' store. */\nexport type AnnexesStore = ReturnType<typeof useCreateAnnexesContext>;\n\n/** Annexes' context. */\nexport const AnnexesContext = createContext<AnnexesContextValue | null>(null);\n\n/** Options used to create the annexes' context. */\nexport interface UseCreateAnnexesContextOptions\n extends Pick<\n AnnexesProps,\n | \"defaultActiveAnnex\"\n | \"activeAnnex\"\n | \"onActiveAnnexChange\"\n | \"onAnnexAdd\"\n | \"onAnnexRemove\"\n > {\n formManager: FormManager;\n basePath: AbsolutePath;\n resolvedAnnexes: ResolvedAnnexObject[];\n}\n\n/** Hook used to create the annexes' context. */\nexport function useCreateAnnexesContext({\n formManager,\n basePath,\n resolvedAnnexes,\n defaultActiveAnnex,\n activeAnnex,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n}: UseCreateAnnexesContextOptions) {\n const setLatestInteraction = useSetLatestInteraction();\n const { activePath, onActivePathChange } = useActivePathContext();\n activeAnnex ??= activePath;\n const latest = useLatestValues({\n printing: usePrinting(),\n formManager,\n onActivePathChange,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n });\n\n const store = useConstant(() =>\n createStore<AnnexesState>()(\n subscribeWithSelector((set, get) => ({\n annexes: resolvedAnnexes,\n activeAnnex:\n activeAnnex === undefined\n ? defaultActiveAnnex == null\n ? null\n : basePath.resolve(defaultActiveAnnex)\n : activeAnnex === null\n ? null\n : basePath.resolve(activeAnnex),\n nextActiveAnnex: null,\n activeAnnexIndex: computed(\n () => [get().activeAnnex, get().tabStates()],\n (activeAnnex, tabStates) =>\n activeAnnex === null\n ? -1\n : tabStates.findIndex((state) => state.path.equals(activeAnnex)),\n ),\n annexStates: [{}],\n repetitiveAnnexStates: [{}],\n tabStates: computed(\n () => [get().annexes, get().annexStates, get().repetitiveAnnexStates],\n (annexes, [annexStates], [repetitiveAnnexStates]) => {\n const tabStates: AnnexState[] = [];\n const pushAnnexState = (path: AbsolutePath) => {\n const state = annexStates[path.toString()];\n if (state != null && !state.isNull) {\n tabStates.push(state);\n }\n };\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const parentPath = annex.path.parent();\n const state = repetitiveAnnexStates[parentPath.toString()];\n if (state?.rowIds) {\n for (const rowId of state.rowIds) {\n pushAnnexState(\n parentPath.append(new AbsolutePathFragment.Id(rowId)),\n );\n }\n }\n } else {\n pushAnnexState(annex.path);\n }\n }\n return tabStates;\n },\n ),\n tablessStates: computed(\n () => [get().annexes, get().annexStates, get().repetitiveAnnexStates],\n (annexes, [annexStates], [repetitiveAnnexStates]) => {\n const tablessStates: (AnnexState | RepetitiveAnnexState)[] = [];\n for (const annex of annexes) {\n let tablessState: AnnexState | RepetitiveAnnexState | null = null;\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n tablessState =\n repetitiveAnnexStates[annex.path.parent().toString()];\n } else {\n const state = annexStates[annex.path.toString()];\n if (state?.isNull) {\n tablessState = state;\n }\n }\n if (tablessState) {\n tablessStates.push(tablessState);\n }\n }\n return tablessStates;\n },\n ),\n waitingRegistration: computed(\n () => [get().annexes, get().annexStates, get().repetitiveAnnexStates],\n (annexes, [annexStates], [repetitiveAnnexStates]) => {\n const waitingRegistration: AbsolutePath[] = [];\n const pushWaitingRegistration = (path: AbsolutePath) => {\n const state = annexStates[path.toString()];\n if (state == null) {\n waitingRegistration.push(path);\n }\n };\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const parentPath = annex.path.parent();\n const state = repetitiveAnnexStates[parentPath.toString()];\n if (!state?.rowIds) {\n waitingRegistration.push(annex.path);\n } else {\n for (const rowId of state.rowIds) {\n pushWaitingRegistration(\n parentPath.append(new AbsolutePathFragment.Id(rowId)),\n );\n }\n }\n } else {\n pushWaitingRegistration(annex.path);\n }\n }\n return waitingRegistration;\n },\n ),\n actions: {\n getAnnexState: (path) =>\n get().annexStates[0][path.toString()] ?? null,\n getRepetitiveAnnexState: (path) =>\n get().repetitiveAnnexStates[0][path.toString()] ?? null,\n setAnnexes: (annexes: ResolvedAnnexObject[]) => {\n const oldActiveAnnexIndex = get().activeAnnexIndex();\n set({\n annexes,\n annexStates: [get().actions.buildAnnexStates(annexes)],\n repetitiveAnnexStates: [\n get().actions.buildRepetitiveAnnexStates(annexes),\n ],\n });\n get().actions.updateActiveAnnex(oldActiveAnnexIndex);\n },\n buildAnnexStates: (\n annexes: ResolvedAnnexObject[] = get().annexes,\n ) => {\n const { getAnnexState, getRepetitiveAnnexState } = get().actions;\n const newAnnexStates: Record<string, AnnexState | null> = {};\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const tablePath = annex.path.parent();\n for (const rowId of getRepetitiveAnnexState(tablePath)\n ?.rowIds ?? []) {\n const rowPath = tablePath.append(\n new AbsolutePathFragment.Id(rowId),\n );\n newAnnexStates[rowPath.toString()] = getAnnexState(rowPath);\n }\n } else {\n newAnnexStates[annex.path.toString()] = getAnnexState(\n annex.path,\n );\n }\n }\n return newAnnexStates;\n },\n buildRepetitiveAnnexStates: (\n annexes: ResolvedAnnexObject[] = get().annexes,\n ) => {\n const { getRepetitiveAnnexState } = get().actions;\n const newRepetitiveAnnexStates: Record<\n string,\n RepetitiveAnnexState | null\n > = {};\n\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const tablePath = annex.path.parent();\n newRepetitiveAnnexStates[tablePath.toString()] =\n getRepetitiveAnnexState(tablePath);\n }\n }\n return newRepetitiveAnnexStates;\n },\n setActiveAnnex: (path: string | Path | null) => {\n if (latest.printing) {\n return;\n }\n\n const newActiveAnnex =\n path === null || path instanceof AbsolutePath\n ? path\n : new AbsolutePath(path);\n const oldActiveAnnex = get().activeAnnex;\n if (!oldActiveAnnex?.equals(newActiveAnnex)) {\n startTransition(() => {\n set({ activeAnnex: newActiveAnnex });\n if (newActiveAnnex != null) {\n setLatestInteraction(newActiveAnnex);\n }\n latest.onActivePathChange(newActiveAnnex);\n latest.onActiveAnnexChange?.(newActiveAnnex);\n });\n }\n },\n updateActiveAnnex: (oldActiveAnnexIndex: number) => {\n if (latest.printing) {\n return;\n }\n\n const tabStates = get().tabStates();\n const nextActiveAnnex = get().nextActiveAnnex;\n if (\n nextActiveAnnex !== null &&\n tabStates.some((state) => state.path.equals(nextActiveAnnex))\n ) {\n set({ nextActiveAnnex: null });\n get().actions.setActiveAnnex(nextActiveAnnex);\n return;\n }\n\n if (\n get().activeAnnex !== null &&\n (tabStates.some((state) =>\n state.path.equals(get().activeAnnex),\n ) ||\n get()\n .waitingRegistration()\n .some((path) => path.contains(get().activeAnnex!)))\n ) {\n return;\n }\n\n get().actions.setActiveAnnex(\n tabStates[\n Math.max(0, Math.min(oldActiveAnnexIndex, tabStates.length - 1))\n ]?.path ?? null,\n );\n },\n registerAnnexState: (path, state) => {\n const oldActiveAnnexIndex = get().activeAnnexIndex();\n const annexStates = get().annexStates[0];\n annexStates[path.toString()] = state;\n set({ annexStates: [annexStates] });\n get().actions.updateActiveAnnex(oldActiveAnnexIndex);\n },\n registerRepetitiveAnnexState: (path, state) => {\n const oldActiveAnnexIndex = get().activeAnnexIndex();\n const repetitiveAnnexStates = get().repetitiveAnnexStates[0];\n repetitiveAnnexStates[path.toString()] = state;\n set({\n annexStates: [get().actions.buildAnnexStates()],\n repetitiveAnnexStates: [repetitiveAnnexStates],\n });\n get().actions.updateActiveAnnex(oldActiveAnnexIndex);\n },\n addAnnex: async (path, toAdd) => {\n const isRepetitive =\n path.lastFragment === AbsolutePathFragment.Wildcard;\n const setPromise = latest.formManager.set(\n isRepetitive\n ? path.parent().append(AbsolutePathFragment.CollectionEnd)\n : path,\n toAdd,\n );\n\n let addedPath: AbsolutePath;\n if (isRepetitive) {\n addedPath = await latest.formManager.get(\n path.parent(),\n (value: Table) =>\n path\n .parent()\n .append(\n new AbsolutePathFragment.Id(\n sliceTable(value, listableSize(value) - 1)[0][0],\n ),\n ),\n );\n } else {\n addedPath = path;\n }\n set({ nextActiveAnnex: addedPath });\n await setPromise;\n latest.onAnnexAdd?.(addedPath);\n },\n removeAnnex: async (path, isRepetitive) => {\n if (isRepetitive) {\n await latest.formManager.remove(path);\n } else {\n await latest.formManager.set(path, null);\n }\n latest.onAnnexRemove?.(path);\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.getState().actions.setAnnexes(resolvedAnnexes);\n if (activeAnnex !== undefined) {\n const {\n activeAnnex: oldActiveAnnex,\n tabStates,\n waitingRegistration,\n } = store.getState();\n const newActiveAnnex =\n mostSpecificPath(\n activeAnnex === null ? null : basePath.resolve(activeAnnex),\n [...tabStates().map((tab) => tab.path), ...waitingRegistration()],\n oldActiveAnnex,\n ) ?? null;\n store.getState().actions.setActiveAnnex(newActiveAnnex);\n }\n }, [resolvedAnnexes, activeAnnex, basePath, store]);\n\n // Set (possibly new) active annex when focused path changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const { activeAnnex, tabStates, waitingRegistration, actions } =\n store.getState();\n actions.setActiveAnnex(\n mostSpecificPath(\n focusedPath,\n [...tabStates().map((tab) => tab.path), ...waitingRegistration()],\n activeAnnex,\n ) ?? null,\n );\n },\n [store],\n ),\n );\n\n return store;\n}\n\n/** Returns the annexes' context. */\nexport function useAnnexesContext(): AnnexesContextValue {\n const annexesContext = useContext(AnnexesContext);\n if (!annexesContext) {\n throw new Error(\"Annexes context not in scope.\");\n }\n return annexesContext;\n}\n\nexport function useAnnexState<T>(\n path: AbsolutePath,\n selector: (state: AnnexState | null) => T,\n): T {\n return useStore(useAnnexesContext(), (state) =>\n selector(state.actions.getAnnexState(path)),\n );\n}\n","import {\n CurrentPath,\n useCurrentPath,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport {\n cx,\n DocumentTitle,\n ErrorBoundary,\n Spinner,\n TabContent,\n usePrinting,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n Suspense,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormAppIssueMessages, FormAppStatus } from \"../FormApp\";\nimport type { IssueMessagesByCode } from \"../IssueMessages\";\nimport type { AnnexObject } from \"./Annexes.tsx\";\nimport { useAnnexesContext, useAnnexState } from \"./AnnexesContext.ts\";\n\n/** Properties of the annex component. */\nexport interface AnnexProps\n extends AnnexObject,\n Omit<\n ComponentPropsWithoutRef<typeof TabContent>,\n \"value\" | \"title\" | \"children\"\n > {\n /** Sets the annex as disabled. */\n disabled?: boolean;\n /** Sets the annex as read-only. */\n readOnly?: boolean;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their code).\n *\n * Provided paths are relative to the annex's path and may contain wildcards,\n * which will have a lower priority when matched against.\n *\n * These messages are used by the `IssueMessages` component.\n *\n * **Note:** Changes to `issueMessages` are handled correctly, but are not\n * efficient. Please make sure that the identity of the provided value doesn't\n * change at every render.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /** Properties to pass to the container element. */\n containerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the `ErrorBoundary` component. */\n errorBoundaryProps?: ComponentPropsWithRef<typeof ErrorBoundary>;\n children?: ReactNode;\n}\n\n/** Component containing the content of an annex. */\nexport const Annex = forwardRef<ComponentRef<typeof TabContent>, AnnexProps>(\n function Annex(\n {\n path,\n // `AnnexObject` props\n title: _title,\n subtitle: _subtitle,\n description: _description,\n issuesPanelLabel: _issuesPanelLabel,\n itemTitle: _itemTitle,\n itemIssuesPanelLabel: _itemIssuesPanelLabel,\n documentTitle: _documentTitle,\n maxAnnexes: _maxAnnexes,\n getValue: _getValue,\n ...otherProps\n },\n forwardedRef,\n ) {\n const annexPath = useResolvedPath(path);\n const store = useAnnexesContext();\n const activeAnnex = useStore(store, (state) => state.activeAnnex);\n const tabStates = useStore(\n store,\n useShallow((state) =>\n state.tabStates().filter((state) => annexPath.contains(state.path)),\n ),\n );\n\n return tabStates.map((state) => {\n const pathStr = state.path.toString();\n return (\n <CurrentPath key={pathStr} path={state.path}>\n <AnnexTabContent\n {...otherProps}\n ref={state.path.equals(activeAnnex) ? forwardedRef : undefined}\n />\n </CurrentPath>\n );\n });\n },\n);\n\ninterface AnnexTabContentProps extends Omit<AnnexProps, keyof AnnexObject> {}\n\nconst AnnexTabContent = forwardRef<\n ComponentRef<typeof TabContent>,\n AnnexTabContentProps\n>(function AnnexTabContent(\n {\n disabled = false,\n readOnly = false,\n issueMessages,\n children,\n className,\n containerProps,\n tabContentLabelProps,\n errorBoundaryProps,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const printing = usePrinting();\n const annexPath = useCurrentPath();\n const documentTitle = useAnnexState(annexPath, (state) =>\n state === null ? null : state.documentTitle,\n );\n\n if (documentTitle === undefined) {\n warnOnce(\n `Annex: At '${annexPath.toString()}': \\`documentTitle\\` ` +\n \"should be set manually since either `title` or `subtitle` is not a \" +\n \"string.\",\n );\n }\n\n return (\n <div\n {...containerProps}\n className={cx(\n prefix(\"annexes__annex-container\"),\n containerProps?.className,\n )}\n >\n <TabContent\n className={cx(prefix(\"annexes__annex\"), className)}\n value={annexPath.toString()}\n tabContentLabelProps={{\n ...tabContentLabelProps,\n className: cx(\n prefix(\"annexes__annex-label\"),\n tabContentLabelProps?.className,\n ),\n }}\n {...otherProps}\n ref={forwardedRef}\n >\n <ErrorBoundary {...errorBoundaryProps}>\n <DocumentTitle\n title={printing ? undefined : (documentTitle ?? undefined)}\n >\n <FormAppStatus disabled={disabled} readOnly={readOnly}>\n <FormAppIssueMessages issueMessages={issueMessages}>\n <Suspense fallback={<Spinner size=\"xl\" color=\"primary\" />}>\n {children}\n </Suspense>\n </FormAppIssueMessages>\n </FormAppStatus>\n </DocumentTitle>\n </ErrorBoundary>\n </TabContent>\n </div>\n );\n});\n","import { AbsolutePath } from \"@ostack.tech/kform\";\nimport { useFormController, useFormManager } from \"@ostack.tech/kform-react\";\nimport { useToastManager } from \"@ostack.tech/ui\";\nimport {\n fileOpen,\n type FileSystemHandle,\n type FileWithHandle,\n supported,\n type WellKnownDirectory,\n} from \"browser-fs-access\";\nimport { type ReactNode, useMemo } from \"react\";\n\nimport { useStartIssuesNavigation } from \"../components/FormApp\";\nimport { useLocale } from \"../providers/LocalizationProvider\";\n\n/**\n * Options that can be passed to the {@link useFormLoader} hook, or to its\n * resulting `load` function.\n */\nexport interface FormLoaderOptions<T = unknown> {\n /**\n * Function used to decode the form, given its file.\n *\n * If decoding a text-based format, one may use `await file.text()` to get the\n * content of the file as a string.\n *\n * @param file File containing the form to decode.\n * @returns Decoded form value.\n */\n decode?: (file: FileWithHandle) => PromiseLike<T>;\n /**\n * Path of the value being loaded.\n *\n * @default AbsolutePath.ROOT\n */\n path?: string | AbsolutePath;\n /** Acceptable file extensions. */\n extensions?: string[];\n /** Acceptable MIME types. */\n mimeTypes?: string[];\n /** Suggested file description. */\n description?: string;\n /** Directory to present when starting to load. */\n startIn?: WellKnownDirectory | FileSystemHandle;\n /**\n * By specifying an ID, the user agent can remember different directories for\n * different IDs.\n */\n id?: string;\n /**\n * Whether to set the form as pristine when it is loaded.\n *\n * @default true\n */\n setPristineOnLoad?: boolean;\n /**\n * Whether to validate the form (and show the issues panel) when it is loaded.\n *\n * @default true\n */\n validateOnLoad?: boolean;\n /**\n * Message to show in a toast when successfully loading a form from a file.\n * Can be set to `null` to not show any message.\n *\n * @param file Loaded file.\n * @returns Message to show in a toast.\n */\n successMessage?: ReactNode | ((file: FileWithHandle) => ReactNode);\n /**\n * Message to show in a toast when an error occurs while loading the form from\n * a file. Can be set to `null` to not show any message.\n *\n * @param file File from which the load was attempted (or `null` if the file\n * could not be accessed).\n * @param error Error that occurred.\n * @returns Message to show in a toast.\n */\n errorMessage?:\n | ReactNode\n | ((file: FileWithHandle | null, error: unknown) => ReactNode);\n}\n\n/** Result of the {@link useFormLoader} hook. */\nexport interface FormLoaderResult<T> {\n /**\n * Function used to load the form.\n *\n * @param options Options used for loading the form.\n * @returns Promise which resolves once the form has been loaded.\n */\n load: (options?: FormLoaderOptions<T>) => Promise<void>;\n /** Whether the browser supports modern file system APIs used for loading. */\n supportsFileSystemAPIs: boolean;\n}\n\n/** Hook exposing a function used to load the form from a file. */\nexport function useFormLoader<T = unknown>({\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n}: FormLoaderOptions<T> = {}): FormLoaderResult<T> {\n const [locale] = useLocale();\n const formManager = useFormManager();\n const { _setState } = useFormController();\n const { addToast } = useToastManager();\n const startIssuesNavigation = useStartIssuesNavigation();\n\n return useMemo(() => {\n async function load({\n decode,\n path = AbsolutePath.ROOT,\n extensions,\n mimeTypes,\n description,\n startIn,\n id = \"\",\n setPristineOnLoad = true,\n validateOnLoad = true,\n successMessage,\n errorMessage,\n }: FormLoaderOptions<T>) {\n if (!decode) {\n throw new Error(\"No `decode` function was provided.\");\n }\n if (successMessage === undefined) {\n successMessage = locale.LoadAction.successMessage;\n }\n if (errorMessage === undefined) {\n errorMessage = locale.LoadAction.errorMessage;\n }\n\n const validationModeIsAuto =\n formManager.autoValidationStatus !== \"inactive\";\n let file: FileWithHandle | null = null;\n try {\n file = await fileOpen({\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n });\n\n _setState({ loading: true } as any);\n const formValue = await decode(file);\n\n // Set validation mode as manual prior to loading the file\n if (validationModeIsAuto) {\n await formManager.setValidationMode(\"manual\");\n }\n\n await formManager.set(path, formValue);\n if (setPristineOnLoad) {\n await formManager.setPristine(path);\n }\n if (validateOnLoad) {\n await startIssuesNavigation();\n }\n\n _setState(\n (state: any) =>\n ({\n latestFileHandles: {\n ...state.latestFileHandles,\n [id]: file!.handle ?? null,\n },\n }) as any,\n );\n\n const message =\n typeof successMessage === \"function\"\n ? successMessage(file)\n : successMessage;\n if (message != null) {\n addToast(message, { severity: \"success\" });\n }\n } catch (err) {\n // User aborted\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(err);\n }\n const message =\n typeof errorMessage === \"function\"\n ? errorMessage(file, err)\n : errorMessage;\n if (message != null) {\n addToast(message, { severity: \"danger\" });\n }\n } finally {\n // Reset validation mode\n if (validationModeIsAuto) {\n await formManager.setValidationMode(\"auto\");\n }\n\n _setState({ loading: false } as any);\n }\n }\n\n return {\n load: (options = {}) =>\n load({\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n ...options,\n }),\n supportsFileSystemAPIs: supported,\n };\n }, [\n _setState,\n formManager,\n startIssuesNavigation,\n locale.LoadAction,\n addToast,\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n ]);\n}\n\n/** Hook exposing whether the form is currently being loaded. */\nexport function useFormIsLoading() {\n return useFormController().useState((state) => (state as any).loading);\n}\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { CurrentPath, useFormattedValue } from \"@ostack.tech/kform-react\";\nimport { usePrinting, useStartPrintingTask } from \"@ostack.tech/ui\";\nimport {\n type ReactNode,\n useCallback,\n useDeferredValue,\n useEffect,\n} from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedAnnexObject,\n useAnnexesContext,\n} from \"./AnnexesContext.ts\";\n\n/** Properties of the `AnnexRegistrar` component. */\nexport interface AnnexRegistrarProps extends ResolvedAnnexObject {\n index?: number;\n}\n\n/** Component used to register a form annex. */\nexport function AnnexRegistrar({\n path,\n title,\n subtitle,\n description,\n issuesPanelLabel,\n itemTitle,\n itemIssuesPanelLabel,\n index,\n documentTitle,\n}: AnnexRegistrarProps) {\n const store = useAnnexesContext();\n\n const printing = usePrinting();\n const finishPrintingTask = useStartPrintingTask();\n const [isNull = true, controller] = useFormattedValue(\n path.append(AbsolutePathFragment.RecursiveWildcard),\n {\n enabled: !useFormIsLoading(),\n onInitialized: finishPrintingTask,\n format: useCallback((value: unknown) => value === null, []),\n },\n );\n const isRepetitive = index != null;\n const absolutePath = controller.usePath();\n const schema = controller.useSchema();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n const dirty = controller.useDirty();\n const value = controller.useValue();\n const deferredValue = useDeferredValue(value);\n const relevantValue = printing ? value : deferredValue;\n const deferredIssuesToDisplay = useDeferredValue(\n controller.useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n const actualTitle = isRepetitive\n ? typeof itemTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : itemTitle(relevantValue, index)\n : itemTitle === undefined\n ? (title as ReactNode)\n : itemTitle\n : typeof title === \"function\"\n ? relevantValue === undefined\n ? null\n : title(relevantValue)\n : title;\n const actualSubtitle =\n typeof subtitle === \"function\"\n ? relevantValue === undefined\n ? null\n : subtitle(relevantValue, index)\n : subtitle;\n const actualDocumentTitle =\n typeof documentTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : documentTitle(relevantValue, index)\n : documentTitle === undefined\n ? (actualTitle === null || typeof actualTitle === \"string\") &&\n (actualSubtitle == null || typeof actualSubtitle === \"string\")\n ? [actualTitle, actualSubtitle].filter((s) => s).join(\" — \")\n : undefined\n : documentTitle;\n\n useEffect(() => {\n if (exists) {\n const { registerAnnexState } = store.getState().actions;\n registerAnnexState(absolutePath, {\n path: absolutePath,\n schema,\n isNull,\n dirty,\n deferredIssuesToDisplay,\n deferredDisplayStatus,\n isRepetitive,\n title: actualTitle,\n subtitle: actualSubtitle,\n documentTitle: actualDocumentTitle,\n description,\n });\n }\n }, [\n absolutePath,\n deferredDisplayStatus,\n deferredIssuesToDisplay,\n description,\n dirty,\n exists,\n isNull,\n isRepetitive,\n actualSubtitle,\n actualTitle,\n schema,\n store,\n subtitle,\n title,\n actualDocumentTitle,\n ]);\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>\n {isRepetitive ? (\n typeof itemIssuesPanelLabel === \"function\" ? (\n deferredValue === undefined ? null : (\n itemIssuesPanelLabel(deferredValue, index)\n )\n ) : itemIssuesPanelLabel === undefined ? (\n (actualSubtitle ?? index + 1)\n ) : (\n itemIssuesPanelLabel\n )\n ) : issuesPanelLabel ? (\n typeof issuesPanelLabel === \"function\" ? (\n deferredValue === undefined ? null : (\n issuesPanelLabel(deferredValue)\n )\n ) : (\n issuesPanelLabel\n )\n ) : (\n <>\n {actualTitle}\n {actualSubtitle && <> — {actualSubtitle}</>}\n </>\n )}\n </CurrentPath>,\n );\n\n return null;\n}\n","import {\n AbsolutePathFragment,\n sliceTable,\n type Table,\n type TableRowId,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n InvalidPathError,\n useFormattedValue,\n} from \"@ostack.tech/kform-react\";\nimport { useStartPrintingTask } from \"@ostack.tech/ui\";\nimport { useCallback, useDeferredValue, useEffect } from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedAnnexObject,\n useAnnexesContext,\n} from \"./AnnexesContext.ts\";\nimport { AnnexRegistrar } from \"./AnnexRegistrar.tsx\";\n\n/** Properties of the `RepetitiveAnnexRegistrar` component. */\nexport interface RepetitiveAnnexRegistrarProps extends ResolvedAnnexObject {}\n\n/** Component used to register a repetitive form annex. */\nexport function RepetitiveAnnexRegistrar({\n path,\n maxAnnexes,\n ...annexProps\n}: RepetitiveAnnexRegistrarProps) {\n const store = useAnnexesContext();\n\n const finishPrintingTask = useStartPrintingTask();\n const [rowIds, controller] = useFormattedValue(path.parent(), {\n enabled: !useFormIsLoading(),\n onInitialized: finishPrintingTask,\n format: useCallback(\n (value?: Table | null): TableRowId[] =>\n value == null ? [] : sliceTable(value).map(([id]) => id),\n [],\n ),\n });\n const schema = controller.useSchema();\n const absolutePath = controller.usePath();\n const deferredIssuesToDisplay = useDeferredValue(\n controller.useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n if (schema.typeInfo.name !== \"Table\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected (possibly nullable) table schema, \" +\n \"but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n useEffect(() => {\n const { registerRepetitiveAnnexState } = store.getState().actions;\n registerRepetitiveAnnexState(absolutePath, {\n rowIds,\n maxAnnexes,\n path: absolutePath,\n schema,\n deferredIssuesToDisplay,\n });\n }, [\n absolutePath,\n deferredDisplayStatus,\n deferredIssuesToDisplay,\n maxAnnexes,\n rowIds,\n schema,\n store,\n ]);\n\n if (\n typeof annexProps.title === \"function\" ||\n typeof annexProps.issuesPanelLabel === \"function\"\n ) {\n throw new Error(\n \"Repetitive annexes must not set `title` or `issuesPanelLabel` as a \" +\n \"function. Use `itemTitle` or `itemIssuesPanelLabel` instead.\",\n );\n }\n\n const actualIssuesPanelLabel = annexProps.issuesPanelLabel\n ? annexProps.issuesPanelLabel\n : annexProps.title;\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>{actualIssuesPanelLabel}</CurrentPath>,\n );\n\n return rowIds?.map((rowId, i) => (\n <AnnexRegistrar\n key={rowId}\n path={absolutePath.append(new AbsolutePathFragment.Id(rowId))}\n index={i}\n {...annexProps}\n />\n ));\n}\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n Path,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n useFormManager,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport { cx, Tabs } from \"@ostack.tech/ui\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useMemo,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { Annex, type AnnexProps } from \"./Annex.tsx\";\nimport { AnnexesContext, useCreateAnnexesContext } from \"./AnnexesContext.ts\";\nimport { AnnexRegistrar } from \"./AnnexRegistrar.tsx\";\nimport { RepetitiveAnnexRegistrar } from \"./RepetitiveAnnexRegistrar.tsx\";\n\n/** Properties of the annexes component. */\nexport interface AnnexesProps\n extends Omit<\n ComponentPropsWithoutRef<typeof Tabs>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"showAllTabsWhilePrinting\"\n > {\n /** Base path for all declared annexes. */\n path?: string | Path;\n /**\n * List of all annexes. When not provided, the list of annexes is obtained\n * from the direct children `Annex` components.\n */\n annexes?: AnnexObject[];\n /** Default active annex. */\n defaultActiveAnnex?: string | Path;\n /** Controlled active annex. */\n activeAnnex?: string | Path;\n /**\n * Function called whenever the active annex changes.\n *\n * @param activeAnnex Path of the new active annex.\n */\n onActiveAnnexChange?: (activeAnnexPath: AbsolutePath | null) => void;\n /**\n * Function called when a new annex is added.\n *\n * @param newAnnexPath Path of the new annex.\n */\n onAnnexAdd?: (newAnnexPath: AbsolutePath) => void;\n /**\n * Function called when an annex is removed.\n *\n * @param removedAnnexPath Path of the removed annex.\n */\n onAnnexRemove?: (removedAnnexPath: AbsolutePath) => void;\n children?: ReactNode;\n}\n\n/** Object representation of an annex. */\nexport interface AnnexObject<T = any> {\n /**\n * Annex path. This path may contain a single wildcard (`*`) at the end, when\n * the elements of a collection should be counted as annexes. Otherwise, the\n * path may contain no other wildcards.\n */\n path?: string | Path;\n /** Annex's title. */\n title?: ReactNode | ((value: T) => ReactNode);\n /** Annex's subtitle. */\n subtitle?: ReactNode | ((value: T, index?: number) => ReactNode);\n /** Annex's description. */\n description?: ReactNode;\n /**\n * Annex's label in the issues panel. The `title` and `subtitle` are used by\n * default.\n */\n issuesPanelLabel?: ReactNode | ((value: T) => ReactNode);\n itemTitle?: ReactNode | ((value: T, index: number) => ReactNode);\n /**\n * Issues panel label for each annex of a collection of annexes. The\n * `subtitle` and index of the item are used by default.\n */\n itemIssuesPanelLabel?: ReactNode | ((value: T, index: number) => ReactNode);\n /**\n * Title of the annex as a string to display in the document's title.\n *\n * Defaults to the `title` together with the `subtitle` (if it exists) when\n * they are strings.\n *\n * A warning is printed if either the title or the subtitle are defined but\n * aren't strings and `documentTitle` is not provided.\n */\n documentTitle?: string | null | ((value: T, index?: number) => string | null);\n /**\n * Maximum number of annexes matching this path that can be added, when\n * counting collection elements as annexes. By default, if the collection has\n * a `MaxSize` validation, then its value is used.\n */\n maxAnnexes?: number;\n /**\n * Function called when an annex matching this path is being added to choose\n * the value that should be added.\n *\n * The default value being added is provided as an argument and may be edited\n * if required.\n *\n * The value to be added should be returned, or a promise that resolves with\n * said value.\n *\n * To prevent an annex from being added, return `undefined`/`null` (or a\n * promise which resolves with `undefined`/`null`).\n *\n * @param value - Value being added, can be edited.\n * @returns Value to be added, `undefined`/`null` if the annex shouldn't be\n * added (or a promise that resolves with said values).\n */\n getValue?: (value: T) => T | null | undefined | Promise<T | null | undefined>;\n}\n\n/** Root component used to render form annexes. */\nexport const Annexes = forwardRef<ComponentRef<typeof Tabs>, AnnexesProps>(\n function Annexes(\n {\n path,\n annexes,\n defaultActiveAnnex,\n activeAnnex,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n variant = \"annexes\",\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n ) {\n const prefix = usePrefix();\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n\n annexes ??= Children.toArray(children)\n .filter(\n (child): child is ReactElement<AnnexProps, typeof Annex> =>\n isValidElement(child) && child.type === Annex,\n )\n .map((annex) => ({\n path: annex.props.path,\n title: annex.props.title,\n subtitle: annex.props.subtitle,\n description: annex.props.description,\n issuesPanelLabel: annex.props.issuesPanelLabel,\n itemTitle: annex.props.itemTitle,\n itemIssuesPanelLabel: annex.props.itemIssuesPanelLabel,\n documentTitle: annex.props.documentTitle,\n maxAnnexes: annex.props.maxAnnexes,\n getValue: annex.props.getValue,\n }));\n\n // Provided annexes but with absolute paths\n const resolvedAnnexes = useMemo(\n () =>\n annexes.map((annex) => ({\n ...annex,\n path: absolutePath.resolve(annex.path ?? Path.CURRENT),\n })),\n [absolutePath, annexes],\n );\n\n // Refuse non-existent paths\n if (!formManager.isValidPath(absolutePath)) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Annexes base path must only contain ids.\");\n }\n // Validate annex paths\n for (const annex of resolvedAnnexes) {\n // Refuse non-existent paths\n if (!formManager.isValidPath(annex.path)) {\n throw new Error(`Invalid path: '${annex.path.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only, or identifiers\n // followed by a wildcard\n if (\n annex.path.fragments.some(\n (frag, i, { length }) =>\n !(frag instanceof AbsolutePathFragment.Id) &&\n (frag !== AbsolutePathFragment.Wildcard || i !== length - 1),\n )\n ) {\n throw new Error(\n \"Annex path must either only contain ids, or ids followed by a \" +\n \"single wildcard at the end.\",\n );\n }\n }\n\n const store = useCreateAnnexesContext({\n formManager,\n basePath: absolutePath,\n resolvedAnnexes,\n defaultActiveAnnex,\n activeAnnex,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n });\n\n const activeAnnexString = useStore(\n store,\n (state) => state.activeAnnex?.toString() ?? \"\",\n );\n const handleValueChange = useCallback(\n (value: string) => store.getState().actions.setActiveAnnex(value),\n [store],\n );\n\n return (\n <CurrentPath path={absolutePath}>\n <AnnexesContext.Provider value={store}>\n {resolvedAnnexes.map((annex) =>\n annex.path.lastFragment === AbsolutePathFragment.Wildcard ? (\n <RepetitiveAnnexRegistrar\n key={annex.path.toString()}\n {...annex}\n />\n ) : (\n <AnnexRegistrar key={annex.path.toString()} {...annex} />\n ),\n )}\n\n <Tabs\n className={cx(prefix(\"annexes\"), className)}\n variant={variant}\n activationMode=\"manual\"\n value={activeAnnexString}\n onValueChange={handleValueChange}\n showAllTabsWhilePrinting\n {...otherProps}\n ref={forwardedRef}\n >\n {children}\n </Tabs>\n </AnnexesContext.Provider>\n </CurrentPath>\n );\n },\n);\n","import { type AbsolutePath, ValidationFailure } from \"@ostack.tech/kform\";\nimport {\n AtPathError,\n type LocatedValidationInfo,\n} from \"@ostack.tech/kform-react\";\nimport { useErrorReporter } from \"@ostack.tech/ui\";\nimport { useEffect } from \"react\";\n\ntype ReportValidationFailuresInfo = Pick<\n LocatedValidationInfo,\n \"path\" | \"issues\"\n>;\n\nclass ValidationFailureError extends AtPathError {\n constructor(path: AbsolutePath, issue: ValidationFailure) {\n super(path, `Failed to run validation '${issue.validation}'`);\n this.name = this.constructor.name;\n this.stack += `\\nCaused by: ${issue.stackTrace}`;\n }\n}\n\n/** Hook used to report validation failures that occur. */\nexport function useReportValidationFailures(\n info?: ReportValidationFailuresInfo[],\n) {\n const reportError = useErrorReporter();\n useEffect(() => {\n if (info) {\n for (const { path, issues } of info) {\n for (const issue of issues) {\n if (issue instanceof ValidationFailure) {\n reportError(new ValidationFailureError(path, issue));\n }\n }\n }\n }\n }, [info, reportError]);\n}\n","import type {\n AbsolutePath,\n FormManager,\n Schema,\n SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport { EMPTY_STORE, useConstant } from \"@ostack.tech/ui\";\nimport { createContext, useContext, useEffect } from \"react\";\nimport { createStore, useStore } from \"zustand\";\n\n/** Value of the control field context. */\nexport type ControlFieldContextValue = ControlFieldStore;\n\n/** State of the control field. */\nexport interface ControlFieldState {\n controlStates: Record<string, ControlState>;\n}\n\n/** State of a control accessible to the whole field. */\nexport interface ControlState {\n formManager: FormManager;\n schema: Schema;\n path: AbsolutePath;\n exists: boolean;\n deferredIssuesToDisplay: SealedValidationIssue[];\n}\n\n/** Control field store. */\nexport type ControlFieldStore = ReturnType<typeof useCreateControlFieldContext>;\n\n/** Control field context. */\nexport const ControlFieldContext =\n createContext<ControlFieldContextValue | null>(null);\n\n/** Hook which creates the control field context value. */\nexport function useCreateControlFieldContext() {\n return useConstant(() =>\n createStore<ControlFieldState>(() => ({\n controlStates: {},\n })),\n );\n}\n\n/** Hook returning the control field's context value. */\nfunction useControlFieldContext(): ControlFieldContextValue | null {\n return useContext(ControlFieldContext);\n}\n\n/** Hook that returns access to the control field's store. */\nexport function useControlFieldStore<T>(\n selector: (state: Partial<ControlFieldState>) => T,\n): T {\n return useStore(useControlFieldContext() ?? EMPTY_STORE, selector);\n}\n\n/** Hook exposing whether a component is being rendered within a control field. */\nexport function useIsInControlField(): boolean {\n return useControlFieldContext() !== null;\n}\n\n/**\n * Hook that makes a control field aware of a controller.\n *\n * The passed `controller` object should not be different on every render.\n */\nexport function useRegisterControllerWithinControlField<T = unknown>(\n controller: Controller<T>,\n deferredIssuesToDisplay: SealedValidationIssue[],\n) {\n const store = useControlFieldContext();\n const formManager = controller.useFormManager();\n const path = controller.usePath();\n const schema = controller.useSchema();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n useEffect(() => {\n if (store) {\n const pathStr = path.toString();\n store.setState((state) => ({\n controlStates: {\n ...state.controlStates,\n [pathStr]: {\n formManager,\n schema,\n path,\n exists,\n deferredIssuesToDisplay,\n },\n },\n }));\n return () => {\n store.setState(\n ({ controlStates: { [pathStr]: _, ...controlStates } }) => ({\n controlStates,\n }),\n );\n };\n }\n }, [deferredIssuesToDisplay, exists, formManager, path, schema, store]);\n}\n","import { Path } from \"@ostack.tech/kform\";\nimport { CurrentPath, useFormManager } from \"@ostack.tech/kform-react\";\nimport { Field } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useEffect,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport {\n ControlFieldContext,\n useCreateControlFieldContext,\n} from \"./ControlFieldContext.ts\";\n\n/** Properties of the control field component. */\nexport interface ControlFieldProps\n extends ComponentPropsWithoutRef<typeof Field> {\n /** Path of the field; inner control paths will be relative to this path. */\n path?: string | Path;\n /**\n * Whether to show the control field.\n *\n * The component will, by default, automatically reset its inner controls when\n * the control field becomes hidden.\n *\n * @default true\n */\n shown?: boolean;\n /**\n * Whether to reset the inner controls when the control field becomes hidden.\n *\n * @default true\n */\n resetOnHide?: boolean;\n /**\n * Whether to set inner controls as untouched when the control field becomes\n * hidden.\n *\n * @default resetOnHide\n */\n setUntouchedOnHide?: boolean;\n /**\n * Whether to set inner controls as pristine when the control field becomes\n * hidden.\n *\n * @default resetOnHide\n */\n setPristineOnHide?: boolean;\n}\n\n/**\n * Component used to group controls with a label, helper text, and/or feedback.\n *\n * The component can be conditionally shown via the `shown` property which, by\n * default, when changing from `true` to `false` will reset its inner controls.\n *\n * Added labels automatically \"point\" to the control and are set to \"required\"\n * when requested by the control.\n *\n * Aria descriptions and error messages are set on the control based on the\n * provided helper texts or feedbacks.\n */\nexport const ControlField = forwardRef<\n ComponentRef<typeof Field>,\n ControlFieldProps\n>(function ControlField(\n {\n path = Path.CURRENT,\n shown = true,\n resetOnHide = true,\n setUntouchedOnHide = resetOnHide,\n setPristineOnHide = resetOnHide,\n ...otherProps\n },\n forwardedRef,\n) {\n const formManager = useFormManager();\n\n // Controllers registered within the control field\n const store = useCreateControlFieldContext();\n\n // Reset registered controllers when `shown` becomes `false`\n const controlStates = useStore(store, (state) => state.controlStates);\n useEffect(() => {\n if (!shown) {\n for (const controlState of Object.values(controlStates)) {\n const { formManager, path, exists } = controlState;\n if (exists) {\n if (resetOnHide) {\n void formManager.reset(path);\n }\n if (setUntouchedOnHide) {\n void formManager.setUntouched(path);\n }\n if (setPristineOnHide) {\n void formManager.setPristine(path);\n }\n }\n }\n }\n }, [\n controlStates,\n formManager,\n resetOnHide,\n setPristineOnHide,\n setUntouchedOnHide,\n shown,\n store,\n ]);\n\n return (\n shown && (\n <CurrentPath path={path}>\n <ControlFieldContext.Provider value={store}>\n <Field {...otherProps} ref={forwardedRef} />\n </ControlFieldContext.Provider>\n </CurrentPath>\n )\n );\n});\n","import type {\n AbsolutePath,\n Schema,\n SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport {\n useDisplayIssueCodesInIssueMessages,\n useRegisteredIssueMessage,\n} from \"../FormApp\";\n\n/** Properties of the issue message component. */\nexport interface IssueMessageProps {\n displayIssueCode?: boolean;\n unknownErrorMessage?: ReactNode;\n unknownWarningMessage?: ReactNode;\n path: AbsolutePath;\n issue: SealedValidationIssue;\n schema: Schema;\n issueCodeProps?: ComponentPropsWithRef<\"span\">;\n}\n\n/** Single issue message within the issue messages or issues panel components. */\nexport function IssueMessage({\n path,\n issue,\n schema,\n displayIssueCode,\n unknownErrorMessage,\n unknownWarningMessage,\n issueCodeProps,\n}: IssueMessageProps) {\n const [locale] = useLocale();\n unknownErrorMessage ??= locale.IssueMessages.unknownErrorMessage;\n unknownWarningMessage ??= locale.IssueMessages.unknownWarningMessage;\n\n let message = useRegisteredIssueMessage(path, issue.code);\n const unknownIssue = message == null;\n if (unknownIssue) {\n message =\n issue.severity === \"error\" ? unknownErrorMessage : unknownWarningMessage;\n // if (process.env.NODE_ENV !== \"production\") {\n // warnOnce(\n // `At '${path.toString()}': no message found for ` +\n // `issue with code: '${issue.code}'.`,\n // );\n // }\n }\n\n const globalDisplayIssueCodes = useDisplayIssueCodesInIssueMessages();\n displayIssueCode ??= globalDisplayIssueCodes;\n\n return (\n <CurrentPath path={path}>\n {typeof message === \"function\"\n ? message(issue.data ?? {}, schema, path)\n : message}\n {(displayIssueCode || unknownIssue) && (\n <span {...issueCodeProps}>({issue.code})</span>\n )}\n </CurrentPath>\n );\n}\n","import type {\n AbsolutePath,\n Path,\n Schema,\n SealedValidationIssue,\n ValidationIssueData,\n} from \"@ostack.tech/kform\";\nimport {\n useFormManager,\n useIssuesTracker,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport { Feedback, FeedbackList } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useDeferredValue,\n useMemo,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useReportValidationFailures } from \"../../utils/useReportValidationFailures.ts\";\nimport { useIsInControlField } from \"../ControlField\";\nimport { useControlFieldStore } from \"../ControlField/ControlFieldContext.ts\";\nimport { FormAppIssueMessages } from \"../FormApp\";\nimport { IssueMessage } from \"../IssueMessage\";\n\n/** Value of an issue message. */\nexport type IssueMessageValue =\n | ReactNode\n | ((\n issueData: ValidationIssueData,\n schema: Schema,\n path: AbsolutePath,\n ) => ReactNode);\n\n/** Mapping of issue message codes to their respective message. */\nexport type IssueMessagesByCode = Record<string, IssueMessageValue>;\n\n/** Properties of the issue messages component. */\nexport interface IssueMessagesProps\n extends ComponentPropsWithoutRef<typeof FeedbackList> {\n /** Path of the value for which to show issues. */\n path?: string | Path;\n /**\n * Issues to show, associated with the provided path. If not provided, the\n * component will query the issues from the form manager.\n */\n issues?: SealedValidationIssue[];\n /** Mapping from an issue's code to its message. */\n messages?: IssueMessagesByCode;\n /**\n * Whether to display issue codes together with each issue message.\n *\n * This property can also be set globally via the `displayIssueCodes` property\n * of the `FormApp`.\n */\n displayIssueCodes?: boolean;\n /**\n * Message to show for an error that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownErrorMessage?: ReactNode;\n /**\n * Message to show for a warning that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownWarningMessage?: ReactNode;\n /**\n * Whether to render the issue messages \"unwrapped\", i.e. outside a containing\n * `FeedbackList`.\n *\n * This is useful together with components such as the `DateRangeControl`\n * where you might want to show issues for multiple paths, all within the same\n * `FeedbackList`:\n *\n * ```tsx\n * <FeedbackList>\n * <IssueMessages path=\"startDate\" unwrapped />\n * <IssueMessages path=\"endDate\" unwrapped />\n * </FeedbackList>;\n * ```\n */\n unwrapped?: boolean;\n}\n\n/**\n * Component used to display all issues associated with the relevant path.\n *\n * Issue messages are automatically read from the scope (typically provided by\n * setting the `issueMessages` property of a `FormApp`, `Annex`, or\n * `FormPage`).\n *\n * Messages may also be passed directly to this component via the `messages`\n * property.\n *\n * If `path` contains an issue without an associated issue message, a generic\n * message is displayed together with a console warning.\n */\nexport const IssueMessages = forwardRef<\n ComponentRef<typeof FeedbackList>,\n IssueMessagesProps\n>(function IssueMessages(\n {\n path,\n issues,\n messages,\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n unwrapped,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const isInControlField = useIsInControlField();\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n const { info } = useIssuesTracker(absolutePath, {\n enabled: !issues && !isInControlField,\n });\n const messagesToRegister = useMemo(\n () => messages && { [absolutePath.toString()]: messages },\n [absolutePath, messages],\n );\n\n const relevantControlState = useControlFieldStore((state) =>\n isInControlField ? state.controlStates?.[absolutePath.toString()] : null,\n );\n const deferredTrackedIssues = useDeferredValue(\n useMemo(() => info?.flatMap((info) => info.issues) ?? [], [info]),\n );\n const deferredIssuesToDisplay = useMemo(\n () =>\n issues ??\n (isInControlField\n ? (relevantControlState?.deferredIssuesToDisplay ?? [])\n : deferredTrackedIssues),\n [\n deferredTrackedIssues,\n isInControlField,\n issues,\n relevantControlState?.deferredIssuesToDisplay,\n ],\n );\n useReportValidationFailures(\n useMemo(\n () => [{ path: absolutePath, issues: deferredIssuesToDisplay }],\n [absolutePath, deferredIssuesToDisplay],\n ),\n );\n\n const schema = useMemo(\n () => relevantControlState?.schema ?? formManager.schema(absolutePath),\n [absolutePath, formManager, relevantControlState?.schema],\n );\n\n const feedbackNodes = useMemo(\n () =>\n deferredIssuesToDisplay.map((issue, i) => (\n <Feedback key={i} type={issue.severity}>\n <IssueMessage\n path={absolutePath}\n issue={issue}\n schema={schema}\n displayIssueCode={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n issueCodeProps={{ className: prefix(\"issue-messages__issue-code\") }}\n />\n </Feedback>\n )),\n [\n deferredIssuesToDisplay,\n absolutePath,\n schema,\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n prefix,\n ],\n );\n\n return (\n <FormAppIssueMessages issueMessages={messagesToRegister}>\n {unwrapped ? (\n feedbackNodes\n ) : (\n <FeedbackList {...otherProps} ref={forwardedRef}>\n {feedbackNodes}\n </FeedbackList>\n )}\n </FormAppIssueMessages>\n );\n});\n","import { AbsolutePath, type Path } from \"@ostack.tech/kform\";\nimport { CurrentPath, useResolvedPath } from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n FeedbackPopover,\n useControllableState,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useIsInControlField } from \"../ControlField\";\nimport { useOnPathFocus } from \"../FormApp\";\n\n/** Properties of the issues popover component. */\nexport interface IssuesPopoverProps\n extends ComponentPropsWithoutRef<typeof FeedbackPopover> {\n path?: string | Path;\n /**\n * Paths relevant to this issues popover. When one of the relevant paths\n * becomes active, the popover will automatically open. Defaults to `[path]`\n * (or `[<current path>]` if no `path` is provided).\n */\n relevantPaths?: (string | Path)[];\n}\n\n/** Component used to display issues within a popover. */\nexport const IssuesPopover = forwardRef<\n ComponentRef<typeof FeedbackPopover>,\n IssuesPopoverProps\n>(function IssuesPopover(\n {\n path,\n relevantPaths,\n defaultOpen,\n open: controlledOpen,\n onOpenChange,\n label,\n ...otherProps\n },\n forwardedRef,\n) {\n const [locale] = useLocale();\n label ??= locale.IssuesPopover.label;\n\n const absolutePath = useResolvedPath(path);\n const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);\n const isInControlField = useIsInControlField();\n\n // Open popover when active path matches the popover's path (unneeded when\n // within a control field)\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n if (\n !isInControlField &&\n (relevantPaths ?? [absolutePath]).some((path) =>\n focusedPath.equals(new AbsolutePath(path)),\n )\n ) {\n setOpen(true);\n }\n },\n [isInControlField, relevantPaths, absolutePath, setOpen],\n ),\n );\n\n return (\n <CurrentPath path={absolutePath}>\n <FeedbackPopover\n open={open}\n onOpenChange={combineEventHandlers(onOpenChange, setOpen)}\n label={label}\n {...otherProps}\n ref={forwardedRef}\n />\n </CurrentPath>\n );\n});\n","import type { DisplayStatus } from \"@ostack.tech/kform\";\nimport type { ControlStatus } from \"@ostack.tech/ui\";\n\n/** Transforms ostack/KForm's display status into ostack/UI's control status. */\nexport function displayStatusToControlStatus(\n displayStatus: DisplayStatus | undefined,\n): ControlStatus | undefined {\n switch (displayStatus) {\n case \"error\":\n return \"invalid\";\n case \"warning\":\n return \"warned\";\n default:\n return undefined;\n }\n}\n\n/** Transforms ostack/KForm's display status into a \"danger\" or \"warning\" colour. */\nexport function displayStatusToColor(\n displayStatus: DisplayStatus | undefined,\n): \"danger\" | \"warning\" | undefined {\n switch (displayStatus) {\n case \"error\":\n return \"danger\";\n case \"warning\":\n return \"warning\";\n default:\n return undefined;\n }\n}\n","import {\n faChevronDown,\n faChevronUp,\n faTrash,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport {\n AbsolutePath,\n AbsolutePathFragment,\n nullableSchemaInnerSchema,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n FormContext,\n useFormContext,\n useFormManager,\n} from \"@ostack.tech/kform-react\";\nimport {\n Button,\n combineEventHandlers,\n controlStatusToAccent,\n cx,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n IconButton,\n useAlertDialog,\n useCombinedRef,\n useControllableState,\n useMediaBreakpointUp,\n VisuallyHidden,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type Dispatch,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { visiblyFocus } from \"../../utils/useControlAutofocus.ts\";\nimport {\n useFormIsDisabled,\n useFormIsReadOnly,\n useIssuesDisplayMode,\n useOnPathFocus,\n} from \"../FormApp\";\nimport { useResetFocus } from \"../FormApp/FormAppContext.ts\";\nimport {\n type ResolvedAnnexObject,\n useAnnexesContext,\n useAnnexState,\n} from \"./AnnexesContext.ts\";\nimport type { AnnexesManager } from \"./AnnexesManager.tsx\";\n\n/** Properties of the annexes' menu. */\nexport interface AnnexesMenuProps\n extends Pick<\n ComponentPropsWithoutRef<typeof AnnexesManager>,\n | \"menuButtonText\"\n | \"addAnnexText\"\n | \"removeAnnexButtonLabel\"\n | \"removeAnnexKeyboardHint\"\n | \"removeAnnexConfirmDialogTitle\"\n | \"removeAnnexConfirmDialogMessage\"\n | \"removeAnnexConfirmDialogOkText\"\n | \"removeAnnexConfirmDialogCancelText\"\n >,\n ComponentPropsWithoutRef<typeof DropdownMenu> {\n menuTriggerProps?: Omit<ComponentPropsWithRef<typeof Button>, \"icon\">;\n menuContentProps?: ComponentPropsWithRef<typeof DropdownMenuContent>;\n}\n\n/** Component that allows to navigate between, add, and remove annexes. */\nexport function AnnexesMenu({\n menuButtonText,\n addAnnexText,\n removeAnnexButtonLabel,\n removeAnnexKeyboardHint,\n removeAnnexConfirmDialogTitle,\n removeAnnexConfirmDialogMessage,\n removeAnnexConfirmDialogOkText,\n removeAnnexConfirmDialogCancelText,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n menuTriggerProps,\n menuContentProps,\n ...otherProps\n}: AnnexesMenuProps) {\n const prefix = usePrefix();\n const formIsReadOnly = useFormIsReadOnly();\n const store = useAnnexesContext();\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n const issuesDisplayMode = useIssuesDisplayMode();\n const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);\n const menuTriggerRef = useRef<HTMLButtonElement | null>(null);\n\n const activeAnnex = useStore(store, (state) => state.activeAnnex);\n const handleRadioGroupValueChange = useCallback(\n (value: string) =>\n store.getState().actions.setActiveAnnex(new AbsolutePath(value)),\n [store],\n );\n\n const annexes = useStore(store, (state) => state.annexes);\n const newItems = useMemo(\n () =>\n annexes.map((annex) => (\n <AnnexesMenuNewItem key={annex.path.toString()} annex={annex} />\n )),\n [annexes],\n );\n const tabStates = useStore(\n store,\n useShallow((state) => state.tabStates()),\n );\n\n // Focus menu trigger when focusing an annex that doesn't exist\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath: AbsolutePath) => {\n if (\n issuesDisplayMode === \"panel\" &&\n menuTriggerRef.current &&\n store\n .getState()\n .tablessStates()\n .some((state) => state.path.equals(focusedPath))\n ) {\n visiblyFocus(menuTriggerRef.current);\n resetFocus();\n }\n },\n [issuesDisplayMode, resetFocus, store],\n ),\n );\n\n const combinedMenuTriggerRef = useCombinedRef(\n menuTriggerRef,\n menuTriggerProps?.ref,\n );\n return (\n <DropdownMenu\n open={open}\n onOpenChange={combineEventHandlers(onOpenChange, setOpen)}\n modal={false}\n {...otherProps}\n >\n <DropdownMenuTrigger>\n <Button\n variant=\"ghost\"\n iconPlacement=\"end\"\n {...menuTriggerProps}\n className={cx(\n prefix(\"annexes__menu-trigger\"),\n menuTriggerProps?.className,\n )}\n icon={open ? faChevronUp : faChevronDown}\n iconProps={{ size: \"2xs\", ...menuTriggerProps?.iconProps }}\n ref={combinedMenuTriggerRef}\n >\n {menuTriggerProps?.children ?? menuButtonText}\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent\n variant=\"subtle\"\n showArrow={false}\n sideOffset={-1}\n avoidCollisions={false}\n align=\"start\"\n {...menuContentProps}\n className={cx(prefix(\"annexes__menu\"), menuContentProps?.className)}\n >\n <DropdownMenuRadioGroup\n value={activeAnnex?.toString()}\n onValueChange={handleRadioGroupValueChange}\n >\n {tabStates.map((state) => (\n <AnnexesMenuItem\n key={state.path.toString()}\n removeAnnexButtonLabel={removeAnnexButtonLabel}\n removeAnnexKeyboardHint={removeAnnexKeyboardHint}\n removeAnnexConfirmDialogTitle={removeAnnexConfirmDialogTitle}\n removeAnnexConfirmDialogMessage={removeAnnexConfirmDialogMessage}\n removeAnnexConfirmDialogOkText={removeAnnexConfirmDialogOkText}\n removeAnnexConfirmDialogCancelText={\n removeAnnexConfirmDialogCancelText\n }\n path={state.path}\n setOpen={setOpen}\n menuRef={menuTriggerRef}\n />\n ))}\n </DropdownMenuRadioGroup>\n {!formIsReadOnly && (\n <DropdownMenuGroup label={isLargeScreen ? undefined : addAnnexText}>\n {isLargeScreen ? (\n <DropdownMenuSub>\n <DropdownMenuSubTrigger\n className={prefix(\"annexes__menu-add-annex\")}\n >\n {addAnnexText}\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent className={prefix(\"annexes__menu-new\")}>\n {newItems}\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n ) : (\n newItems\n )}\n </DropdownMenuGroup>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/** Properties of an item in the annexes' menu. */\ninterface AnnexesMenuItemProps\n extends Pick<\n ComponentPropsWithoutRef<typeof AnnexesManager>,\n | \"removeAnnexButtonLabel\"\n | \"removeAnnexKeyboardHint\"\n | \"removeAnnexConfirmDialogTitle\"\n | \"removeAnnexConfirmDialogMessage\"\n | \"removeAnnexConfirmDialogOkText\"\n | \"removeAnnexConfirmDialogCancelText\"\n > {\n path: AbsolutePath;\n setOpen: Dispatch<boolean>;\n menuRef: RefObject<HTMLButtonElement | null>;\n}\n\n/** Item in the annexes' menu. */\nfunction AnnexesMenuItem({\n removeAnnexButtonLabel,\n removeAnnexKeyboardHint,\n removeAnnexConfirmDialogTitle,\n removeAnnexConfirmDialogMessage,\n removeAnnexConfirmDialogOkText,\n removeAnnexConfirmDialogCancelText,\n path,\n setOpen,\n menuRef,\n}: AnnexesMenuItemProps) {\n const prefix = usePrefix();\n const store = useAnnexesContext();\n const formContext = useFormContext();\n const formIsDisabled = useFormIsDisabled();\n const formIsReadOnly = useFormIsReadOnly();\n const { confirm } = useAlertDialog();\n\n const deferredDisplayStatus = useAnnexState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const isRemovable = useAnnexState(\n path,\n (state) =>\n state != null && (state.schema.typeInfo.nullable || state.isRepetitive),\n );\n const title = useAnnexState(path, (state) => state?.title);\n const subtitle = useAnnexState(path, (state) => state?.subtitle);\n const nonRepetitiveDescription = useAnnexState(\n path,\n (state) => state && !state.isRepetitive && state.description,\n );\n\n const removeAnnex = async () => {\n const { getAnnexState, removeAnnex } = store.getState().actions;\n const state = getAnnexState(path);\n if (!state) {\n return;\n }\n\n if (\n !state.dirty ||\n (await confirm(\n // The form context will typically not be in the scope of the alert\n // dialog, so we need to provide it\n <FormContext.Provider value={{ ...formContext, currentPath: path }}>\n {removeAnnexConfirmDialogMessage?.(\n <strong>\n {state.title}\n {state.subtitle && <> — {state.subtitle}</>}\n </strong>,\n )}\n </FormContext.Provider>,\n {\n title: removeAnnexConfirmDialogTitle,\n color: \"danger\",\n okText: removeAnnexConfirmDialogOkText,\n cancelText: removeAnnexConfirmDialogCancelText,\n triggerElement: menuRef.current,\n },\n ))\n ) {\n void removeAnnex(state.path, state.isRepetitive);\n setOpen(false);\n }\n };\n\n const handleItemKeyDown = (evt: KeyboardEvent) => {\n if (\n isRemovable &&\n !formIsDisabled &&\n !formIsReadOnly &&\n evt.key === \"Delete\"\n ) {\n void removeAnnex();\n }\n };\n const handleRemoveButtonClick = (evt: MouseEvent) => {\n evt.stopPropagation();\n void removeAnnex();\n };\n\n return (\n <DropdownMenuRadioItem\n color=\"primary\"\n data-status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-accent={controlStatusToAccent(\n displayStatusToControlStatus(deferredDisplayStatus),\n )}\n showRadio={false}\n value={path.toString()}\n className={prefix(\"annexes__menu-annex\")}\n actionProps={{\n className: prefix(\"annexes__menu-annex-action\"),\n }}\n contentProps={{\n className: prefix(\"annexes__menu-annex-content\"),\n }}\n onKeyDown={handleItemKeyDown}\n >\n <CurrentPath path={path}>\n <div className={prefix(\"annexes__menu-annex-content-container\")}>\n <div className={prefix(\"annexes__menu-annex-title\")}>\n {title}\n {subtitle && (\n <span className={prefix(\"annexes__menu-annex-subtitle\")}>\n {subtitle}\n </span>\n )}\n </div>\n {nonRepetitiveDescription && (\n <div className={prefix(\"annexes__menu-annex-description\")}>\n {nonRepetitiveDescription}\n </div>\n )}\n </div>\n {isRemovable && !formIsReadOnly && (\n <>\n {removeAnnexKeyboardHint && (\n <VisuallyHidden>{removeAnnexKeyboardHint}</VisuallyHidden>\n )}\n <IconButton\n className={prefix(\"annexes__menu-annex-remove\")}\n icon={faTrash}\n label={removeAnnexButtonLabel ?? \"\"}\n color=\"danger\"\n circle\n disabled={formIsDisabled}\n onClick={handleRemoveButtonClick}\n aria-hidden=\"true\"\n />\n </>\n )}\n </CurrentPath>\n </DropdownMenuRadioItem>\n );\n}\n\n/** Properties of a new item in the annexes' menu. */\ninterface AnnexManagerNewItemProps {\n annex: ResolvedAnnexObject;\n}\n\n/** New item in the annexes' menu. */\nfunction AnnexesMenuNewItem({ annex }: AnnexManagerNewItemProps) {\n const prefix = usePrefix();\n const formIsDisabled = useFormIsDisabled();\n const formManager = useFormManager();\n const store = useAnnexesContext();\n\n const isRepetitive =\n annex.path.lastFragment === AbsolutePathFragment.Wildcard;\n const title = useStore(store, (state) =>\n isRepetitive\n ? (annex.title as ReactNode)\n : state.actions.getAnnexState(annex.path)?.title,\n );\n\n const canBeAdded = useStore(store, (state) => {\n let canBeAdded = false;\n if (isRepetitive) {\n const annexState = state.actions.getRepetitiveAnnexState(\n annex.path.parent(),\n );\n if (!annexState) {\n return false;\n }\n let maxSize = annexState.maxAnnexes;\n // Read max size from the schema restrictions if not defined\n if (maxSize == null) {\n const { restrictions } = annexState.schema.typeInfo;\n if (typeof restrictions.maxSize === \"number\") {\n maxSize = restrictions.maxSize;\n }\n }\n canBeAdded =\n maxSize == null ||\n (annexState.rowIds != null && annexState.rowIds.length < maxSize);\n } else {\n const annexState = state.actions.getAnnexState(annex.path);\n canBeAdded = annexState?.isNull ?? false;\n }\n return canBeAdded;\n });\n\n const [gettingValue, setGettingValue] = useState(false);\n const handleItemSelect = useCallback(async () => {\n const schema = formManager.schema(annex.path);\n const initialValue = schema.typeInfo.nullable\n ? nullableSchemaInnerSchema(schema).initialValue\n : schema.initialValue;\n\n let toAdd = initialValue;\n if (annex.getValue) {\n try {\n setGettingValue(true);\n toAdd = await annex.getValue(await schema.clone(initialValue));\n } finally {\n setGettingValue(false);\n }\n }\n\n if (toAdd == null) {\n return;\n }\n\n // Add new annex\n void store.getState().actions.addAnnex(annex.path, toAdd);\n }, [annex, formManager, store]);\n\n return (\n <DropdownMenuItem\n color=\"primary\"\n className={prefix(\"annexes__menu-new-annex\")}\n disabled={formIsDisabled || !canBeAdded || gettingValue}\n onSelect={handleItemSelect}\n contentProps={{\n className: prefix(\"annexes__menu-new-annex-content\"),\n }}\n >\n <CurrentPath path={isRepetitive ? annex.path.parent() : annex.path}>\n <div className={prefix(\"annexes__menu-new-annex-title\")}>{title}</div>\n {annex.description && (\n <div className={prefix(\"annexes__menu-new-annex-description\")}>\n {annex.description}\n </div>\n )}\n </CurrentPath>\n </DropdownMenuItem>\n );\n}\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport { boolDataAttr, Tab } from \"@ostack.tech/ui\";\nimport { useCallback, useRef } from \"react\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { visiblyFocus } from \"../../utils/useControlAutofocus.ts\";\nimport { useIssuesDisplayMode, useOnPathFocus } from \"../FormApp\";\nimport { useResetFocus } from \"../FormApp/FormAppContext.ts\";\nimport { IssueMessages } from \"../IssueMessages\";\nimport { IssuesPopover } from \"../IssuesPopover\";\nimport { useAnnexState } from \"./AnnexesContext.ts\";\n\nexport interface AnnexTabProps {\n path: AbsolutePath;\n}\n\nexport function AnnexTab({ path }: AnnexTabProps) {\n const prefix = usePrefix();\n const issuesDisplayMode = useIssuesDisplayMode();\n const deferredIssuesToDisplay = useAnnexState(\n path,\n useShallow(\n (state) =>\n (issuesDisplayMode === \"inline\" && state?.deferredIssuesToDisplay) ||\n [],\n ),\n );\n const deferredDisplayStatus = useAnnexState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const title = useAnnexState(path, (state) => state?.title);\n const subtitle = useAnnexState(path, (state) => state?.subtitle);\n\n const tabRef = useRef<HTMLButtonElement | null>(null);\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath: AbsolutePath) => {\n if (tabRef.current && path.equals(focusedPath)) {\n // In inline mode the issues popover should get focused instead\n if (issuesDisplayMode === \"panel\") {\n visiblyFocus(tabRef.current);\n }\n // Let the annex be opened before resetting focus\n setTimeout(() => resetFocus());\n }\n },\n [issuesDisplayMode, path, resetFocus],\n ),\n );\n\n return (\n <>\n <Tab\n className={prefix(\"annexes__tab\")}\n value={path.toString()}\n status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-has-issues={boolDataAttr(deferredIssuesToDisplay.length > 0)}\n tabInnerProps={{ className: prefix(\"annexes__tab-inner\") }}\n ref={tabRef}\n >\n <CurrentPath path={path}>\n <span className={prefix(\"annexes__tab-title\")}>{title}</span>\n {subtitle && (\n <span className={prefix(\"annexes__tab-subtitle\")}>{subtitle}</span>\n )}\n </CurrentPath>\n </Tab>\n\n {issuesDisplayMode === \"inline\" && (\n <IssuesPopover\n path={path}\n buttonContainerProps={{\n className: prefix(\"annexes__tab-issues-popover-button-container\"),\n }}\n iconButtonProps={{\n className: prefix(\"annexes__tab-issues-popover-button\"),\n }}\n >\n <IssueMessages issues={deferredIssuesToDisplay} />\n </IssuesPopover>\n )}\n </>\n );\n}\n","import { cx, TabList, useMediaBreakpointUp } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useAnnexesContext } from \"./AnnexesContext.ts\";\nimport { AnnexTab } from \"./AnnexTab.tsx\";\n\n/** Properties of the annex tab list component. */\nexport interface AnnexTabListProps\n extends ComponentPropsWithoutRef<typeof TabList> {\n hideNonActiveOnSmallScreens: boolean;\n}\n\n/** List of annex tabs. */\nexport const AnnexesTabList = forwardRef<\n ComponentRef<typeof TabList>,\n AnnexTabListProps\n>(function AnnexManager(\n { hideNonActiveOnSmallScreens, rootProps, className, ...otherProps },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const store = useAnnexesContext();\n const activeAnnex = useStore(store, (state) => state.activeAnnex);\n const tabStates = useStore(\n store,\n useShallow((state) => state.tabStates()),\n );\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n\n return (\n <TabList\n className={cx(prefix(\"annexes__tab-list\"), className)}\n {...otherProps}\n rootProps={{\n ...rootProps,\n className: cx(prefix(\"annexes__tab-list-root\"), rootProps?.className),\n }}\n ref={forwardedRef}\n >\n {tabStates.map((state) =>\n !hideNonActiveOnSmallScreens ||\n isLargeScreen ||\n state.path.equals(activeAnnex) ? (\n <AnnexTab key={state.path.toString()} {...state} />\n ) : null,\n )}\n </TabList>\n );\n});\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { useFormManager } from \"@ostack.tech/kform-react\";\nimport {\n type Button,\n cx,\n type DropdownMenu,\n type DropdownMenuContent,\n FeedbackList,\n type TabList,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useIssuesDisplayMode } from \"../FormApp\";\nimport { IssueMessages } from \"../IssueMessages\";\nimport { IssuesPopover } from \"../IssuesPopover\";\nimport {\n type AnnexState,\n type RepetitiveAnnexState,\n useAnnexesContext,\n} from \"./AnnexesContext.ts\";\nimport { AnnexesMenu } from \"./AnnexesMenu.tsx\";\nimport { AnnexesTabList } from \"./AnnexesTabList.tsx\";\n\n/** Properties of the annexes' manager component. */\nexport interface AnnexesManagerProps extends ComponentPropsWithoutRef<\"nav\"> {\n /** Text of the menu button. */\n menuButtonText?: ReactNode;\n /** Text of the \"add annex\" item. */\n addAnnexText?: ReactNode;\n /** Label of the remove annex button, announced by assistive technologies. */\n removeAnnexButtonLabel?: string;\n /**\n * Hint on how to remove an annex via keyboard, announced by assistive\n * technologies.\n */\n removeAnnexKeyboardHint?: string;\n /** Title of the \"remove annex\" confirm dialog. */\n removeAnnexConfirmDialogTitle?: ReactNode;\n /**\n * Function that should return the message of the \"remove annex\" confirm\n * dialog, given a node with the name of the annex.\n *\n * @param annexName Node containing the name of the annex.\n */\n removeAnnexConfirmDialogMessage?: (annexName: ReactNode) => ReactNode;\n /** Text of the \"remove annex\" confirm dialog OK button. */\n removeAnnexConfirmDialogOkText?: ReactNode;\n /** Text of the \"remove annex\" confirm dialog cancel button. */\n removeAnnexConfirmDialogCancelText?: ReactNode;\n /** Properties to pass to the menu container element. */\n menuContainerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the menu trigger component. */\n menuTriggerProps?: Omit<ComponentPropsWithRef<typeof Button>, \"icon\">;\n /** Properties to pass to the menu content component. */\n menuContentProps?: ComponentPropsWithRef<typeof DropdownMenuContent>;\n /** Properties to pass to the menu component. */\n menuProps?: ComponentPropsWithRef<typeof DropdownMenu>;\n /** Properties to pass to the tab-list container element. */\n tabListContainerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the tab-list component. */\n tabListProps?: ComponentPropsWithRef<typeof TabList>;\n}\n\n/**\n * Component used to manage the form's annexes. Provides a menu that allows\n * changing, adding, and removing annexes, as well as a list of tabs for each\n * existing annex.\n */\nexport const AnnexesManager = forwardRef<\n ComponentRef<\"nav\">,\n AnnexesManagerProps\n>(function AnnexManager(\n {\n menuButtonText,\n addAnnexText,\n removeAnnexButtonLabel,\n removeAnnexKeyboardHint,\n removeAnnexConfirmDialogTitle,\n removeAnnexConfirmDialogMessage,\n removeAnnexConfirmDialogOkText,\n removeAnnexConfirmDialogCancelText,\n className,\n \"aria-label\": ariaLabel,\n menuContainerProps,\n menuTriggerProps,\n menuContentProps,\n menuProps,\n tabListContainerProps,\n tabListProps,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n ariaLabel ??= locale.AnnexesManager[\"aria-label\"];\n menuButtonText ??= locale.AnnexesManager.menuButtonText;\n addAnnexText ??= locale.AnnexesManager.addAnnexText;\n removeAnnexButtonLabel ??= locale.AnnexesManager.removeAnnexButtonLabel;\n removeAnnexKeyboardHint ??= locale.AnnexesManager.removeAnnexKeyboardHint;\n removeAnnexConfirmDialogTitle ??=\n locale.AnnexesManager.removeAnnexConfirmDialogTitle;\n removeAnnexConfirmDialogMessage ??=\n locale.AnnexesManager.removeAnnexConfirmDialogMessage;\n removeAnnexConfirmDialogOkText ??=\n locale.AnnexesManager.removeAnnexConfirmDialogOkText;\n removeAnnexConfirmDialogCancelText ??=\n locale.AnnexesManager.removeAnnexConfirmDialogCancelText;\n const store = useAnnexesContext();\n const issuesDisplayMode = useIssuesDisplayMode();\n const tablessStates: (AnnexState | RepetitiveAnnexState)[] = useStore(\n store,\n useShallow((state) =>\n issuesDisplayMode === \"inline\" ? state.tablessStates() : [],\n ),\n );\n const tablessPaths = useMemo(\n () => tablessStates.map((state) => state.path),\n [tablessStates],\n );\n const deferredTablessIssuesToDisplay = useMemo(\n () => tablessStates.map((state) => state.deferredIssuesToDisplay || []),\n [tablessStates],\n );\n const formManager = useFormManager();\n const shouldRenderMenu = useStore(store, (state) =>\n state.annexes.some(\n (annex) =>\n annex.path.lastFragment === AbsolutePathFragment.Wildcard ||\n formManager.schema(annex.path).typeInfo.nullable,\n ),\n );\n\n return (\n <nav\n className={cx(prefix(\"annexes__manager\"), className)}\n aria-label={ariaLabel}\n {...otherProps}\n ref={forwardedRef}\n >\n {shouldRenderMenu && (\n <div\n {...menuContainerProps}\n className={cx(\n prefix(\"annexes__menu-container\"),\n menuContainerProps?.className,\n )}\n >\n <AnnexesMenu\n menuButtonText={menuButtonText}\n addAnnexText={addAnnexText}\n removeAnnexButtonLabel={removeAnnexButtonLabel}\n removeAnnexKeyboardHint={removeAnnexKeyboardHint}\n removeAnnexConfirmDialogTitle={removeAnnexConfirmDialogTitle}\n removeAnnexConfirmDialogMessage={removeAnnexConfirmDialogMessage}\n removeAnnexConfirmDialogOkText={removeAnnexConfirmDialogOkText}\n removeAnnexConfirmDialogCancelText={\n removeAnnexConfirmDialogCancelText\n }\n {...menuProps}\n menuTriggerProps={menuTriggerProps}\n menuContentProps={menuContentProps}\n />\n </div>\n )}\n\n {shouldRenderMenu && issuesDisplayMode === \"inline\" && (\n <IssuesPopover\n buttonContainerProps={{\n className: prefix(\"annexes__issues-popover-container\"),\n }}\n relevantPaths={tablessPaths}\n >\n <FeedbackList>\n {tablessStates.map((state, i) => (\n <IssueMessages\n key={state.path.toString()}\n path={state.path}\n issues={deferredTablessIssuesToDisplay[i] ?? []}\n unwrapped\n />\n ))}\n </FeedbackList>\n </IssuesPopover>\n )}\n\n <div\n {...tabListContainerProps}\n className={cx(\n prefix(\"annexes__tab-list-container\"),\n tabListContainerProps?.className,\n )}\n >\n <AnnexesTabList\n hideNonActiveOnSmallScreens={shouldRenderMenu}\n {...tabListProps}\n />\n </div>\n </nav>\n );\n});\n","import type { SealedValidationIssue } from \"@ostack.tech/kform\";\nimport { FeedbackList, useIsInTableCell } from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { useIssuesDisplayMode } from \"../components/FormApp\";\nimport {\n IssueMessages,\n type IssueMessagesByCode,\n} from \"../components/IssueMessages\";\nimport { IssuesPopover } from \"../components/IssuesPopover\";\n\n/** Options of the `useControlIssues` hook. */\nexport interface UseControlIssuesOptions {\n /** Mapping from path to issues to display. */\n issuesToDisplay: Record<string, SealedValidationIssue[]>;\n /** Mapping from path to issue messages by code. */\n issueMessages?: Record<string, IssueMessagesByCode | undefined>;\n /** Whether issues should be displayed. */\n displayIssues?: boolean;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Hook which helps a control component render its issues.\n *\n * This hook returns a pair containing two React nodes:\n *\n * - The first element of the pair contains the node that should be rendered when\n * the issues are to appear inline. This will be `null` if the issues should\n * not appear inline.\n * - The second element of the pair contains the node that should be rendered when\n * the issues are to appear within a popover. This will be `null` if the\n * issues should not appear in a popover.\n */\nexport function useControlIssues({\n issuesToDisplay,\n issueMessages,\n displayIssues = true,\n issueMessagesProps,\n}: UseControlIssuesOptions): [ReactNode, ReactNode] {\n const issuesDisplayMode = useIssuesDisplayMode();\n const isInTableCell = useIsInTableCell();\n\n const {\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n ...feedbackListProps\n } = issueMessagesProps ?? {};\n const issuesNode = displayIssues && (\n <FeedbackList {...feedbackListProps} hidden={issuesDisplayMode === \"panel\"}>\n {Object.entries(issuesToDisplay).map(([path, issues], i) => (\n <IssueMessages\n key={i}\n path={path}\n issues={issues}\n messages={issueMessages?.[path]}\n displayIssueCodes={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n unwrapped\n />\n ))}\n </FeedbackList>\n );\n if (issuesDisplayMode === \"panel\") {\n return [issuesNode, null];\n }\n return [\n isInTableCell ? null : issuesNode,\n isInTableCell ? <IssuesPopover>{issuesNode}</IssuesPopover> : null,\n ];\n}\n","import type {\n AbsolutePath,\n DisplayStatus,\n SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport {\n useDataTableColumnLabel,\n useOnFieldLabelChange,\n usePrinting,\n useStartPrintingTask,\n} from \"@ostack.tech/ui\";\nimport {\n type FocusEvent,\n type ReactNode,\n type Ref,\n type RefObject,\n useCallback,\n useDeferredValue,\n useEffect,\n useImperativeHandle,\n useMemo,\n} from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useRegisterControllerWithinControlField } from \"../components/ControlField\";\nimport {\n useFormIsDisabled,\n useFormIsReadOnly,\n useRegisterController,\n useRegisterLabel,\n} from \"../components/FormApp\";\nimport {\n useFormAppContext,\n useSetLatestInteraction,\n} from \"../components/FormApp/FormAppContext.ts\";\nimport { useControlAutofocus } from \"./useControlAutofocus.ts\";\n\n/** Options when registering the control. */\nexport interface UseRegisterControlOptions<T> {\n controller: Controller<T>;\n issuesPanelLabel?: ReactNode;\n ariaLabel?: string;\n issuesPanelLabelSuffix?: ReactNode;\n preventAutoFocus?: boolean;\n apiRef?: Ref<Controller<T> | undefined>;\n}\n\n/** Result of registering the control. */\nexport interface UseRegisterControlResult<TElem> {\n displayLoading: boolean;\n displayDisabled: boolean;\n displayReadOnly: boolean;\n displayStatusToDisplay: DisplayStatus | undefined;\n issuesToDisplay: SealedValidationIssue[];\n autofocusRef: RefObject<TElem | null>;\n handleFocus: (event: FocusEvent) => void;\n}\n\n/** Hook used to register a control within the form app. */\nexport function useRegisterControl<T, TElem extends HTMLElement = HTMLElement>({\n controller,\n issuesPanelLabel,\n ariaLabel,\n issuesPanelLabelSuffix,\n preventAutoFocus,\n apiRef,\n}: UseRegisterControlOptions<T>): UseRegisterControlResult<TElem> {\n const printing = usePrinting();\n const { useState, usePath, useInitialized, useDisplayStatus } = controller;\n const path = usePath();\n const formIsDisabled = useFormIsDisabled();\n const displayDisabled =\n useState((state) => !state.initialized || !state.exists) || formIsDisabled;\n const displayReadOnly = useFormIsReadOnly();\n const deferredIsValidating = useDeferredValue(\n useState((state) => state.validationStatus === \"validating\"),\n );\n const initialized = useInitialized();\n const displayLoading = !initialized || deferredIsValidating;\n const displayStatusToDisplay = useDeferredValue(useDisplayStatus());\n const issuesToDisplay = useDeferredValue(\n useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n\n // Start a printing task until the control is initialised\n const finishPrintingTask = useStartPrintingTask();\n useEffect(() => {\n if (initialized) {\n finishPrintingTask();\n }\n }, [finishPrintingTask, initialized]);\n\n // Register the issues panel label\n const columnLabel = useDataTableColumnLabel();\n useRegisterLabel(\n path,\n issuesPanelLabel || columnLabel || ariaLabel,\n issuesPanelLabel ? 1 : -1,\n );\n useRegisterFieldLabel(path, issuesPanelLabelSuffix);\n\n // Register the controller within its control field\n useRegisterControllerWithinControlField(controller, issuesToDisplay);\n\n // Register the controller in the form app\n useRegisterController(controller);\n\n // Expose the control's API via `apiRef`\n useImperativeHandle(apiRef, () => controller, [controller]);\n\n // Autofocus control when the active path changes\n const autofocusRef = useControlAutofocus<T, TElem>(\n controller,\n !preventAutoFocus && !printing,\n );\n\n // Handle control focus\n const setLatestInteraction = useSetLatestInteraction();\n const handleFocus = useCallback(\n (event: FocusEvent) => {\n if (\n !printing &&\n event.target === event.currentTarget &&\n !event.defaultPrevented\n ) {\n setLatestInteraction(controller.getState().path);\n }\n },\n [controller, printing, setLatestInteraction],\n );\n\n return useMemo(\n () => ({\n displayLoading: printing ? false : displayLoading,\n displayDisabled: printing ? false : displayDisabled,\n displayReadOnly: printing ? false : displayReadOnly,\n displayStatusToDisplay: printing ? undefined : displayStatusToDisplay,\n issuesToDisplay: printing ? [] : issuesToDisplay,\n autofocusRef,\n handleFocus,\n }),\n [\n autofocusRef,\n displayDisabled,\n displayLoading,\n displayReadOnly,\n displayStatusToDisplay,\n handleFocus,\n issuesToDisplay,\n printing,\n ],\n );\n}\n\n/** Hook used to register a label for all control field's controls. */\nfunction useRegisterFieldLabel(\n path: AbsolutePath,\n issuesPanelLabelSuffix?: ReactNode,\n) {\n const { store: formAppStore } = useFormAppContext();\n useOnFieldLabelChange(\n useCallback(\n (label) =>\n formAppStore.getState().actions.registerLabel(\n path,\n label && issuesPanelLabelSuffix ? (\n <>\n {label}\n {issuesPanelLabelSuffix}\n </>\n ) : (\n label\n ),\n ),\n [formAppStore, issuesPanelLabelSuffix, path],\n ),\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n InvalidPathError,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n Checkbox,\n type CheckboxChecked,\n combineEventHandlers,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type Dispatch,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the checkbox control component. */\nexport interface CheckboxControlProps<T extends boolean | null = boolean | null>\n extends Omit<\n InputOptions<T, CheckboxChecked, ComponentRef<typeof Checkbox>>,\n \"enabled\" | \"format\" | \"parse\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Checkbox>,\n \"defaultChecked\" | \"checked\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | InputController<T, CheckboxChecked, ComponentRef<typeof Checkbox>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Checkbox control component supporting (possibly nullable) schemas of type\n * \"Boolean\". `null` values are represented as an \"indeterminate\" checkbox.\n */\nexport const CheckboxControl = forwardRef(function CheckboxControl<\n T extends boolean | null = boolean | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n onFocus,\n onCheckedChange,\n onBlurToOutside,\n ...otherProps\n }: CheckboxControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Checkbox>>,\n) {\n const [formattedValue, setFormattedValue] = useState<CheckboxChecked>(false);\n const controller = useInput<\n T,\n CheckboxChecked,\n ComponentRef<typeof Checkbox>\n >(path, {\n enabled: !useFormIsLoading(),\n parse: parseCheckboxValue,\n format: formatToCheckboxValue,\n setFormattedValue,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLButtonElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n if (schema.typeInfo.name !== \"Boolean\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n \"booleans, but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedCheckboxRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Checkbox\n checked={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n onCheckedChange={combineEventHandlers(\n onCheckedChange,\n combineEventHandlers(\n inputProps.onChange,\n setFormattedValue as Dispatch<CheckboxChecked>,\n ),\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedCheckboxRef}\n />\n {inlineIssues}\n {popoverIssues}\n </>\n );\n});\n\n/** Parses a checkbox control formatted value. */\nfunction parseCheckboxValue<T extends boolean | null>(\n formattedValue: CheckboxChecked,\n state: FormatterControllerState<T, CheckboxChecked>,\n): T {\n return (\n formattedValue === \"indeterminate\"\n ? state.schema.typeInfo.nullable\n ? null\n : state.schema.initialValue\n : formattedValue\n ) as T;\n}\n\n/** Formats a checkbox control value. */\nfunction formatToCheckboxValue<T extends boolean | null>(\n value: T | undefined,\n): CheckboxChecked {\n return value === undefined ? false : (value ?? \"indeterminate\");\n}\n","import type { Schema } from \"@ostack.tech/kform\";\nimport { equals, type Listable } from \"@ostack.tech/kform-react\";\nimport { Option, OptionsGroup } from \"@ostack.tech/ui\";\nimport type { JSX } from \"react\";\n\nimport type { OptionObject, OptionsGroupObject } from \"./options.ts\";\n\n/**\n * Parses a selection value from the (string) index of an option (or empty\n * string).\n */\nexport function parseSelectionValueFromOptionIndex<T>(\n formattedValue: string,\n schema: Schema<T>,\n options: { value: T }[],\n): T {\n if (formattedValue === \"\") {\n return schema.typeInfo.nullable ? (null as T) : schema.initialValue;\n }\n return options[+formattedValue].value;\n}\n\n/**\n * Formats a selection value as the (string) index of an option (or empty\n * string).\n */\nexport function formatSelectionValueAsOptionIndex<T>(\n value: T | undefined,\n options: { value: T }[],\n): string {\n const idx = options.findIndex((option) => equals(option.value, value));\n return idx === -1 ? \"\" : idx.toString();\n}\n\n/** Parses an array of selection values from an array of (string) option indices. */\nexport function parseSelectionValuesFromOptionIndices<\n T,\n TListable extends Listable<T> | null,\n>(\n formattedValue: string[],\n schema: Schema<TListable>,\n options: { value: T }[],\n): T[] | null {\n if (formattedValue.length === 0) {\n return schema.typeInfo.nullable ? null : [];\n }\n return formattedValue.map((idx) => options[+idx].value);\n}\n\n/** Formats an array of selection values as an array of (string) option indices. */\nexport function formatSelectionValuesAsOptionIndices<T>(\n arrayValue: T[] | null | undefined,\n options: { value: T }[],\n): string[] {\n return (\n arrayValue?.map((v) => {\n const idx = options.findIndex((option) => equals(option.value, v));\n return idx === -1 ? \"\" : idx.toString();\n }) ?? []\n );\n}\n\n/**\n * Transforms option objects into React nodes.\n *\n * @param options Option objects.\n * @returns React nodes representing the objects.\n */\nexport function optionObjectsToNodes<T>(\n options: (OptionsGroupObject<T> | OptionObject<T>)[],\n): JSX.Element[] {\n let optionIndex = 0;\n return options.map(({ key, ...optionOrGroup }, i) =>\n \"options\" in optionOrGroup ? (\n <OptionsGroup key={key ?? i} {...optionOrGroup}>\n {optionOrGroup.options.map(\n ({ key, value, text, ...optionProps }, i) => (\n <Option key={key ?? i} value={optionIndex++} {...optionProps}>\n {text ?? value?.toString() ?? \"\"}\n </Option>\n ),\n )}\n </OptionsGroup>\n ) : (\n <Option key={key ?? i} {...optionOrGroup} value={optionIndex++}>\n {optionOrGroup.text ?? optionOrGroup.value?.toString() ?? \"\"}\n </Option>\n ),\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Listable,\n type ListableInputController,\n type ListableInputOptions,\n useListableInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n Checkbox,\n CheckboxGroup,\n combineEventHandlers,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type Key,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport {\n formatSelectionValuesAsOptionIndices,\n parseSelectionValuesFromOptionIndices,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Checkbox in object notation. */\nexport type CheckboxObject<T = unknown> = Omit<\n ComponentPropsWithRef<typeof Checkbox>,\n \"defaultChecked\" | \"checked\" | \"value\" | \"children\"\n> & {\n /** Option value. */\n value: T;\n /** Option's rendered text. */\n text?: ReactNode;\n /** Option's unique key. */\n key?: Key;\n};\n\n/** Properties of the checkbox group control component. */\nexport interface CheckboxGroupControlProps<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n> extends Omit<\n ListableInputOptions<\n T,\n TListable,\n string[],\n ComponentRef<typeof CheckboxGroup>\n >,\n \"enabled\" | \"formatFromArray\" | \"parseToArray\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof CheckboxGroup>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"children\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /** Checkbox group control options. */\n options: CheckboxObject<T>[];\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | ListableInputController<\n T,\n TListable,\n string[],\n ComponentRef<typeof CheckboxGroup>\n >\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Checkbox group control component supporting (possibly nullable) listable\n * schemas with elements of any type.\n *\n * If the schema is nullable, this component sets the form value to `null` when\n * the control contains no elements. Note, however, that the form may still hold\n * an empty listable as value if set programmatically.\n */\nexport const CheckboxGroupControl = forwardRef(function CheckboxGroupControl<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n>(\n {\n path,\n options,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: CheckboxGroupControlProps<T, TListable>,\n forwardedRef: ForwardedRef<ComponentRef<typeof CheckboxGroup>>,\n) {\n const [arrayValue, setArrayValue] = useState<T[] | null>(null);\n const formattedValue = useMemo(\n () => formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options, arrayValue],\n );\n const controller = useListableInput<\n T,\n TListable,\n string[],\n ComponentRef<typeof CheckboxGroup>\n >(path, {\n enabled: !useFormIsLoading(),\n parseToArray: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n formatFromArray: useCallback(\n (arrayValue: T[] | null) =>\n formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { getState, useSchema, usePath, inputProps } = controller;\n const { restrictions } = useSchema().typeInfo;\n const absolutePath = usePath();\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<TListable, HTMLDivElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string[]) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n getState().schema,\n options,\n ),\n ),\n [getState, options],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedCheckboxGroupRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <CheckboxGroup\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedCheckboxGroupRef}\n >\n {options.map(({ value, text, key, ...checkboxProps }, i) => (\n <Checkbox key={key ?? i} value={i} {...checkboxProps}>\n {text ?? value?.toString() ?? \"\"}\n </Checkbox>\n ))}\n </CheckboxGroup>\n {inlineIssues}\n {popoverIssues}\n </>\n );\n});\n","import type { Schema } from \"@ostack.tech/kform\";\nimport {\n formatTemporalAsString,\n type Temporal,\n} from \"@ostack.tech/kform-react\";\nimport { addDays, max, min, parseISO } from \"date-fns\";\n\n/** Returns the minimum date allowed based on a temporal schema's restrictions. */\nexport function minDateRestriction<T extends Temporal | null>(\n schema: Schema<T>,\n): Date | undefined {\n const { restrictions } = schema.typeInfo;\n const min = temporalRestrictionToDate(restrictions.min, schema);\n const exclusiveMin = temporalRestrictionToDate(\n restrictions.exclusiveMin,\n schema,\n );\n const minFromMinExclusive = exclusiveMin && addDays(exclusiveMin, 1);\n return min != null && minFromMinExclusive != null\n ? max([min, minFromMinExclusive])\n : (min ?? minFromMinExclusive);\n}\n\n/** Returns the maximum date allowed based on a temporal schema's restrictions. */\nexport function maxDateRestriction<T extends Temporal | null>(\n schema: Schema<T>,\n): Date | undefined {\n const { restrictions } = schema.typeInfo;\n const max = temporalRestrictionToDate(restrictions.max, schema);\n const exclusiveMax = temporalRestrictionToDate(\n restrictions.exclusiveMax,\n schema,\n );\n const maxFromMaxExclusive = exclusiveMax && addDays(exclusiveMax, -1);\n return max != null && maxFromMaxExclusive != null\n ? min([max, maxFromMaxExclusive])\n : (max ?? maxFromMaxExclusive);\n}\n\n/** Transforms a temporal restriction in a JS date. */\nfunction temporalRestrictionToDate<T extends Temporal | null>(\n restriction: unknown,\n schema: Schema<T>,\n) {\n return restriction == null\n ? undefined\n : parseISO(formatTemporalAsString(restriction as T, schema));\n}\n","import type { Schema } from \"@ostack.tech/kform\";\nimport type { Temporal } from \"@ostack.tech/kform-react\";\nimport {\n type DateFormatterOptions,\n type DateParserOptions,\n type DateTransformerOptions,\n useDateTransformer,\n} from \"@ostack.tech/ui\";\nimport { format as fnsFormat, parseISO } from \"date-fns\";\nimport { useMemo } from \"react\";\n\n/** Temporal string transformer. */\nexport interface TemporalStringTransformer {\n /**\n * Function used to parse a formatted date as exposed by a date input as a\n * temporal string.\n */\n parse: <T extends Temporal | null = Temporal | null>(\n formattedDate: string,\n schema: Schema<T>,\n options?: DateParserOptions,\n ) => string;\n /**\n * Function used to format a temporal string as a string accepted by a date\n * input.\n */\n format: <T extends Temporal | null = Temporal | null>(\n temporalString: string,\n schema: Schema<T>,\n options?: DateFormatterOptions,\n ) => string;\n}\n\n/**\n * Hook exposing functions to transform a temporal string value from/into a\n * string representation of a date accepted by a date input.\n */\nexport function useTemporalStringTransformer(\n dateTransformerOptions?: DateTransformerOptions,\n): TemporalStringTransformer {\n const { format, parse } = useDateTransformer(dateTransformerOptions);\n\n return useMemo(\n () => ({\n parse: <T extends Temporal | null = Temporal | null>(\n formattedDate: string,\n schema: Schema<T>,\n options?: DateParserOptions,\n ) => {\n const date = parse(formattedDate, options);\n if (date === null) {\n return \"\";\n }\n\n const dateString = fnsFormat(date, \"yyyy-MM-dd\");\n switch (schema.typeInfo.name) {\n case \"Instant\":\n return `${dateString}T00:00:00.000Z`;\n case \"LocalDateTime\":\n return `${dateString}T00:00:00`;\n default: // `LocalDate` or JavaScript `Date`\n return dateString;\n }\n },\n format: <T extends Temporal | null = Temporal | null>(\n temporalString: string,\n _schema: Schema<T>,\n options?: DateFormatterOptions,\n ) => temporalString && format(parseISO(temporalString), options),\n }),\n [format, parse],\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Temporal,\n type TemporalInputController,\n type TemporalInputOptions,\n useTemporalInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n DateInput,\n type DateValueRepresentations,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useState,\n} from \"react\";\n\nimport {\n maxDateRestriction,\n minDateRestriction,\n} from \"../../utils/dateRestrictions.ts\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport { useTemporalStringTransformer } from \"../../utils/useTemporalStringTransformer.ts\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the date control component. */\nexport interface DateControlProps<T extends Temporal | null = Temporal | null>\n extends Omit<\n TemporalInputOptions<T, string, ComponentRef<typeof DateInput>>,\n \"enabled\" | \"formatFromString\" | \"parseToString\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof DateInput>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | TemporalInputController<T, string, ComponentRef<typeof DateInput>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Date control component supporting nullable temporal schemas. */\nexport const DateControl = forwardRef(function DateControl<\n T extends Temporal | null = Temporal | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n required,\n minDate,\n maxDate,\n loading,\n disabled,\n readOnly,\n onFocus,\n onBlurToOutside,\n endAdornment,\n ...otherProps\n }: DateControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof DateInput>>,\n) {\n const { format, parse } = useTemporalStringTransformer({\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n });\n\n const [formattedValue, setFormattedValue] = useState(\"\");\n const controller = useTemporalInput<\n T,\n string,\n ComponentRef<typeof DateInput>\n >(path, {\n enabled: !useFormIsLoading(),\n parseToString: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n parse(formattedValue, state.schema),\n [parse],\n ),\n formatFromString: useCallback(\n (temporalString: string, state: FormatterControllerState<T, string>) =>\n format(temporalString, state.schema),\n [format],\n ),\n setFormattedValue,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLInputElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n ({ formattedValue }: DateValueRepresentations) => {\n setFormattedValue(formattedValue);\n inputProps.onChange(formattedValue);\n },\n [inputProps],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedDateInputRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <DateInput\n value={formattedValue}\n name={inputProps.name}\n locale={dateFnsLocale}\n shortFormat={shortFormat}\n fullFormat={fullFormat}\n required={required ?? restrictions.required === true}\n minDate={minDate ?? minDateRestriction(schema)}\n maxDate={maxDate ?? maxDateRestriction(schema)}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={handleValueChange}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedDateInputRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Temporal,\n type TemporalInputController,\n type TemporalInputOptions,\n useTemporalInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n DateRangeInput,\n type DateRangeValueRepresentations,\n type StringRange,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport {\n maxDateRestriction,\n minDateRestriction,\n} from \"../../utils/dateRestrictions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport { useTemporalStringTransformer } from \"../../utils/useTemporalStringTransformer.ts\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the date-range control component. */\nexport interface DateRangeControlProps<\n TStart extends Temporal | null = Temporal | null,\n TEnd extends Temporal | null = TStart,\n> extends Omit<\n ComponentPropsWithoutRef<typeof DateRangeInput>,\n \"defaultValue\" | \"value\"\n > {\n /** Path to the start value. */\n startPath: string | Path;\n /** Path to the end value. */\n endPath: string | Path;\n /**\n * Issue messages of this control's start.\n *\n * Mapping from an issue's code to its message.\n */\n startIssueMessages?: IssueMessagesByCode;\n /**\n * Issue messages of this control's end.\n *\n * Mapping from an issue's code to its message.\n */\n endIssueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Label suffix to use in the issues panel when displaying issues associated\n * with this field's start date.\n */\n issuesPanelStartLabelSuffix?: ReactNode;\n /**\n * Label suffix to use in the issues panel when displaying issues associated\n * with this field's end date.\n */\n issuesPanelEndLabelSuffix?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the start control's API. */\n startApiRef?: Ref<TemporalInputController<TStart, string> | undefined>;\n /** Reference to the end control's API. */\n endApiRef?: Ref<TemporalInputController<TEnd, string> | undefined>;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n onStartInitialized?: TemporalInputOptions<TStart, string>[\"onInitialized\"];\n onStartFormManagerEvent?: TemporalInputOptions<\n TStart,\n string\n >[\"onFormManagerEvent\"];\n onStartValueChange?: TemporalInputOptions<TStart, string>[\"onValueChange\"];\n onStartValidationStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onValidationStatusChange\"];\n onStartDisplayStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onDisplayStatusChange\"];\n onStartDirtyStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onDirtyStatusChange\"];\n onStartTouchedStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onTouchedStatusChange\"];\n onEndInitialized?: TemporalInputOptions<TEnd, string>[\"onInitialized\"];\n onEndFormManagerEvent?: TemporalInputOptions<\n TEnd,\n string\n >[\"onFormManagerEvent\"];\n onEndValueChange?: TemporalInputOptions<TEnd, string>[\"onValueChange\"];\n onEndValidationStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onValidationStatusChange\"];\n onEndDisplayStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onDisplayStatusChange\"];\n onEndDirtyStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onDirtyStatusChange\"];\n onEndTouchedStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onTouchedStatusChange\"];\n}\n\n/** Date-range control component supporting nullable temporal schemas. */\nexport const DateRangeControl = forwardRef(function DateRangeControl<\n TStart extends Temporal | null = Temporal | null,\n TEnd extends Temporal | null = TStart,\n>(\n {\n startPath,\n endPath,\n startIssueMessages,\n endIssueMessages,\n issuesPanelLabel,\n issuesPanelStartLabelSuffix,\n issuesPanelEndLabelSuffix,\n displayIssues = true,\n preventAutoFocus,\n startApiRef,\n endApiRef,\n issueMessagesProps,\n required,\n minDate,\n maxDate,\n startLoading,\n endLoading,\n disabled,\n readOnly,\n startInputProps,\n endInputProps,\n onStartInitialized,\n onStartFormManagerEvent,\n onStartValueChange,\n onStartValidationStatusChange,\n onStartDisplayStatusChange,\n onStartDirtyStatusChange,\n onStartTouchedStatusChange,\n onEndInitialized,\n onEndFormManagerEvent,\n onEndValueChange,\n onEndValidationStatusChange,\n onEndDisplayStatusChange,\n onEndDirtyStatusChange,\n onEndTouchedStatusChange,\n onValueChange,\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n onBlurToOutside,\n endAdornment,\n ...otherProps\n }: DateRangeControlProps<TStart, TEnd>,\n forwardedRef: ForwardedRef<ComponentRef<typeof DateRangeInput>>,\n) {\n const [locale] = useLocale();\n issuesPanelStartLabelSuffix ??=\n locale.DateRangeControl.issuesPanelStartLabelSuffix;\n issuesPanelEndLabelSuffix ??=\n locale.DateRangeControl.issuesPanelEndLabelSuffix;\n\n const { format, parse } = useTemporalStringTransformer({\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n });\n\n const [formattedValue, setFormattedValue] = useState<StringRange>({\n start: \"\",\n end: \"\",\n });\n const parseToString = useCallback(\n (\n formattedValue: string,\n state: FormatterControllerState<TStart | TEnd, string>,\n ) => parse(formattedValue, state.schema),\n [parse],\n );\n const formatFromString = useCallback(\n (\n stringValue: string,\n state: FormatterControllerState<TStart | TEnd, string>,\n ) => format(stringValue, state.schema),\n [format],\n );\n const formIsLoading = useFormIsLoading();\n const startController = useTemporalInput<TStart, string>(startPath, {\n enabled: !formIsLoading,\n parseToString,\n formatFromString,\n setFormattedValue: useCallback(\n (formattedValue: string) =>\n setFormattedValue(({ end }) => ({ start: formattedValue, end })),\n [],\n ),\n onInitialized: onStartInitialized,\n onFormManagerEvent: onStartFormManagerEvent,\n onValueChange: onStartValueChange,\n onValidationStatusChange: onStartValidationStatusChange,\n onDisplayStatusChange: onStartDisplayStatusChange,\n onDirtyStatusChange: onStartDirtyStatusChange,\n onTouchedStatusChange: onStartTouchedStatusChange,\n });\n const endController = useTemporalInput<TEnd, string, HTMLInputElement>(\n endPath,\n {\n enabled: !formIsLoading,\n parseToString,\n formatFromString,\n setFormattedValue: useCallback(\n (formattedValue: string) =>\n setFormattedValue(({ start }) => ({ start, end: formattedValue })),\n [],\n ),\n onInitialized: onEndInitialized,\n onFormManagerEvent: onEndFormManagerEvent,\n onValueChange: onEndValueChange,\n onValidationStatusChange: onEndValidationStatusChange,\n onDisplayStatusChange: onEndDisplayStatusChange,\n onDirtyStatusChange: onEndDirtyStatusChange,\n onTouchedStatusChange: onEndTouchedStatusChange,\n },\n );\n const { inputProps: startControllerInputProps } = startController;\n const startSchema = startController.useSchema();\n const startAbsolutePath = startController.usePath();\n const { restrictions: startRestrictions } = startSchema.typeInfo;\n const { inputProps: endControllerInputProps } = endController;\n const endSchema = endController.useSchema();\n const endAbsolutePath = endController.usePath();\n const { restrictions: endRestrictions } = endSchema.typeInfo;\n\n // Register the start control\n const {\n displayLoading: displayStartLoading,\n displayDisabled: displayStartDisabled,\n displayReadOnly: displayStartReadOnly,\n displayStatusToDisplay: startDisplayStatusToDisplay,\n issuesToDisplay: startIssuesToDisplay,\n autofocusRef: startAutofocusRef,\n handleFocus: handleStartFocus,\n } = useRegisterControl<TStart, HTMLInputElement>({\n controller: startController,\n issuesPanelLabel,\n ariaLabel: startInputProps?.[\"aria-label\"],\n issuesPanelLabelSuffix: issuesPanelStartLabelSuffix,\n preventAutoFocus,\n apiRef: startApiRef,\n });\n // Register the end control\n const {\n displayLoading: displayEndLoading,\n displayDisabled: displayEndDisabled,\n displayReadOnly: displayEndReadOnly,\n displayStatusToDisplay: endDisplayStatusToDisplay,\n issuesToDisplay: endIssuesToDisplay,\n autofocusRef: endAutofocusRef,\n handleFocus: handleEndFocus,\n } = useRegisterControl<TEnd, HTMLInputElement>({\n controller: endController,\n issuesPanelLabel,\n ariaLabel: endInputProps?.[\"aria-label\"],\n issuesPanelLabelSuffix: issuesPanelEndLabelSuffix,\n preventAutoFocus,\n apiRef: endApiRef,\n });\n\n const handleValueChange = useCallback(\n ({ formattedValue: newFormattedValue }: DateRangeValueRepresentations) => {\n setFormattedValue(newFormattedValue);\n if (newFormattedValue.start !== formattedValue.start) {\n startControllerInputProps.onChange(newFormattedValue.start);\n }\n if (newFormattedValue.end !== formattedValue.end) {\n endControllerInputProps.onChange(newFormattedValue.end);\n }\n },\n [\n endControllerInputProps,\n formattedValue.end,\n formattedValue.start,\n startControllerInputProps,\n ],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [startAbsolutePath.toString()]: startIssuesToDisplay,\n [endAbsolutePath.toString()]: endIssuesToDisplay,\n },\n issueMessages: {\n [startAbsolutePath.toString()]: startIssueMessages,\n [endAbsolutePath.toString()]: endIssueMessages,\n },\n displayIssues,\n issueMessagesProps,\n });\n\n return (\n <>\n <DateRangeInput\n value={formattedValue}\n locale={dateFnsLocale}\n shortFormat={shortFormat}\n fullFormat={fullFormat}\n required={\n required ??\n (startRestrictions.required === true ||\n endRestrictions.required === true)\n }\n minDate={minDate ?? minDateRestriction(startSchema)}\n maxDate={maxDate ?? maxDateRestriction(endSchema)}\n startLoading={displayStartLoading || startLoading}\n endLoading={displayEndLoading || endLoading}\n disabled={(displayStartDisabled && displayEndDisabled) || disabled}\n readOnly={\n (displayStartReadOnly && displayEndReadOnly) ||\n readOnly ||\n (startInputProps?.readOnly && endInputProps?.readOnly)\n }\n status={\n startDisplayStatusToDisplay === \"error\" ||\n endDisplayStatusToDisplay === \"error\"\n ? \"invalid\"\n : startDisplayStatusToDisplay === \"warning\" ||\n endDisplayStatusToDisplay === \"warning\"\n ? \"warned\"\n : undefined\n }\n onValueChange={combineEventHandlers(onValueChange, handleValueChange)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n combineEventHandlers(\n startControllerInputProps.onBlur,\n endControllerInputProps.onBlur,\n ),\n )}\n startInputProps={{\n name: startControllerInputProps.name,\n ...startInputProps,\n disabled: displayStartDisabled,\n readOnly: displayStartReadOnly || startInputProps?.readOnly,\n onFocus: combineEventHandlers(\n startInputProps?.onFocus,\n handleStartFocus,\n ),\n ref: useCombinedRef(\n startControllerInputProps?.ref,\n useCombinedRef(startAutofocusRef, startInputProps?.ref),\n ),\n }}\n endInputProps={{\n name: endControllerInputProps.name,\n ...endInputProps,\n disabled: displayEndDisabled,\n readOnly: displayEndReadOnly || endInputProps?.readOnly,\n onFocus: combineEventHandlers(endInputProps?.onFocus, handleEndFocus),\n ref: useCombinedRef(\n endControllerInputProps?.ref,\n useCombinedRef(endAutofocusRef, endInputProps?.ref),\n ),\n }}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n {...otherProps}\n ref={forwardedRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import { faDownload, faFileLines } from \"@fortawesome/free-solid-svg-icons\";\nimport type { File as KFormFile, Path } from \"@ostack.tech/kform\";\nimport {\n type FileInputController,\n type FileInputOptions,\n useFileInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n Alert,\n combineEventHandlers,\n ControlAddon,\n Dialog,\n DialogBody,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n Icon,\n IconButton,\n Input,\n Tooltip,\n useCombinedRef,\n usePrintClassNames,\n} from \"@ostack.tech/ui\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/**\n * File control's interaction with the selected file:\n *\n * - `view`: A button is added which opens a dialog to view and optionally\n * download the file. A fallback alert is displayed when the file cannot be\n * viewed.\n * - `download`: A button is added to download the file. Useful if you know that\n * the accepted file types aren't viewable in the browser.\n * - `none`: No interaction with the selected file is added.\n */\nexport type FileControlFileInteraction = \"view\" | \"download\" | \"none\";\n\n/** Properties of the file control component. */\nexport interface FileControlProps<T extends KFormFile | null = KFormFile | null>\n extends Omit<\n FileInputOptions<T, FileList, ComponentRef<typeof Input>>,\n \"enabled\" | \"formatFromFileList\" | \"parseToFileList\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Input>,\n // TODO: Support `multiple`\n | \"type\"\n | \"multiple\"\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"status\"\n | \"align\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n FileInputController<T, FileList, ComponentRef<typeof Input>> | undefined\n >;\n /**\n * Type of interaction with the selected file.\n *\n * @default view\n */\n fileInteraction?: FileControlFileInteraction;\n /** Label of the button used to open the file viewer. */\n viewFileButtonLabel?: ReactNode;\n /** Label of the button used to download the file. */\n downloadFileButtonLabel?: ReactNode;\n /** Text displayed when the file cannot be viewed. */\n fallbackText?: ReactNode;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** File control component supporting (possibly nullable) file schemas. */\nexport const FileControl = forwardRef(function FileControl<\n T extends KFormFile | null = KFormFile | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n fileInteraction = \"view\",\n viewFileButtonLabel,\n downloadFileButtonLabel,\n fallbackText,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n accept,\n loading,\n disabled,\n readOnly,\n showClearButton,\n endAdornment,\n onChange,\n onKeyDown,\n onFocus,\n onBlurToOutside,\n clearButtonProps,\n ...otherProps\n }: FileControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Input>>,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n viewFileButtonLabel ??= locale.FileControl.viewFileButtonLabel;\n downloadFileButtonLabel ??= locale.FileControl.downloadFileButtonLabel;\n fallbackText ??= locale.FileControl.fallbackText;\n const { printHidden } = usePrintClassNames();\n\n // Keep track of the latest file list to work around some browsers clearing\n // the input on \"cancel\"\n const latestFileList = useRef<FileList | null>(null);\n const [file, setFile] = useState<File | null>(null);\n const controller = useFileInput<T, FileList, ComponentRef<typeof Input>>(\n path,\n {\n enabled: !useFormIsLoading(),\n formManager,\n formatFromFileList: useCallback((fileList: FileList) => {\n setFile(fileList.length === 0 ? null : fileList[0]);\n latestFileList.current = fileList;\n return fileList;\n }, []),\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n },\n );\n const { useSchema, usePath, inputProps } = controller;\n const { nullable, restrictions } = useSchema().typeInfo;\n const absolutePath = usePath();\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLInputElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n // Prevent browsers from clearing the input on \"cancel\" by undoing clearings\n // that didn't originate from a click on the clear button or via\n // delete/backspace. This undoing is done by setting the input's `files` to\n // the latest seen file list.\n showClearButton ??= nullable ? \"auto\" : false;\n const isClearing = useRef(false);\n const handleClearButtonClick = useCallback(() => {\n isClearing.current = true;\n }, []);\n const handleChange = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n if (evt.target.files!.length > 0 || isClearing.current) {\n isClearing.current = false;\n onChange?.(evt);\n inputProps.onChange(evt);\n } else {\n evt.target.files = latestFileList.current;\n }\n },\n [inputProps, onChange],\n );\n\n // Clear file when pressing 'Delete' or 'Backspace'\n const clearButtonRef = useRef<HTMLButtonElement | null>(null);\n const handleKeyDown = useCallback((evt: KeyboardEvent) => {\n if (evt.code === \"Delete\" || evt.code === \"Backspace\") {\n clearButtonRef.current?.click();\n }\n }, []);\n\n // File content as a data URL\n const dataURL = useMemo(\n () =>\n fileInteraction !== \"none\" && file ? URL.createObjectURL(file) : null,\n [file, fileInteraction],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedInputRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Input\n type=\"file\"\n name={inputProps.name}\n required={required ?? restrictions.required == true}\n accept={\n accept ??\n (Array.isArray(restrictions.acceptedFileTypes)\n ? restrictions.acceptedFileTypes.join()\n : undefined)\n }\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n showClearButton={showClearButton}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n onChange={handleChange}\n onKeyDown={combineEventHandlers(onKeyDown, handleKeyDown, {\n checkDefaultPrevented: true,\n })}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n clearButtonProps={{\n ...clearButtonProps,\n onClick: combineEventHandlers(\n clearButtonProps?.onClick,\n handleClearButtonClick,\n ),\n ref: useCombinedRef(clearButtonProps?.ref, clearButtonRef),\n }}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n\n {/* View file adornment */}\n {fileInteraction === \"view\" && file && (\n <Dialog>\n <Tooltip content={viewFileButtonLabel}>\n <DialogTrigger>\n <ControlAddon asChild>\n <button type=\"button\" className={printHidden}>\n <Icon fixedWidth icon={faFileLines} />\n </button>\n </ControlAddon>\n </DialogTrigger>\n </Tooltip>\n\n <DialogContent\n variant=\"subtle\"\n className={prefix(\"file-control__viewer-dialog\")}\n aria-describedby={undefined}\n >\n <DialogHeader>\n <DialogTitle\n className={prefix(\"file-control__viewer-dialog-title\")}\n >\n {file.name}\n </DialogTitle>\n\n {/* Download file */}\n <IconButton\n variant=\"ghost\"\n className={prefix(\"file-control__viewer-download\")}\n asChild\n icon={faDownload}\n label={downloadFileButtonLabel}\n >\n <a href={dataURL!} download={file.name} />\n </IconButton>\n </DialogHeader>\n\n <DialogBody\n className={prefix(\"file-control__viewer-dialog-body\")}\n >\n {/* File viewer */}\n <object\n className={prefix(\"file-control__viewer-object\")}\n type={file.type || undefined}\n data={dataURL!}\n aria-label={file.name}\n >\n <Alert\n className={prefix(\"file-control__viewer-fallback\")}\n severity=\"warning\"\n >\n {fallbackText}\n </Alert>\n </object>\n </DialogBody>\n </DialogContent>\n </Dialog>\n )}\n\n {/* File download adornment */}\n {fileInteraction === \"download\" && file && (\n <Tooltip content={downloadFileButtonLabel}>\n <ControlAddon asChild>\n <a\n className={printHidden}\n href={dataURL!}\n download={file.name}\n >\n <Icon icon={faDownload} />\n </a>\n </ControlAddon>\n </Tooltip>\n )}\n </>\n }\n {...otherProps}\n ref={combinedInputRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import {\n AbsolutePath,\n type DisplayStatus,\n type Path,\n type SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport {\n computed,\n useConstant,\n useLatestValues,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { useActivePathContext } from \"../../providers/ActivePathProvider\";\nimport { mostSpecificPath } from \"../../utils/mostSpecificPath.ts\";\nimport { useOnPathFocus } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport type { FormPageObject, FormPagesProps } from \"./FormPages.tsx\";\n\n/** Value of the form pages context. */\nexport type FormPagesContextValue = FormPagesStore;\n\n/** Resolved form page object. */\nexport interface ResolvedFormPageObject extends FormPageObject {\n path: AbsolutePath;\n}\n\n/** Form page state. */\nexport interface FormPageState {\n path: AbsolutePath;\n exists: boolean;\n deferredDisplayStatus: DisplayStatus | undefined;\n deferredIssuesToDisplay: SealedValidationIssue[];\n title?: ReactNode;\n documentTitle?: string | null;\n code?: ReactNode;\n}\n\n/** State of the form pages. */\nexport interface FormPagesState {\n pages: ResolvedFormPageObject[];\n activePage: AbsolutePath | null;\n activePageIndex: () => number;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new object\n // instances\n pageStates: [Record<string, FormPageState | null>];\n pageHeaderHeights: [Map<string, number>];\n navigationSelectHeight: number;\n actions: FormPagesActions;\n}\n\n/** Actions of the form pages. */\nexport interface FormPagesActions {\n getPageState: (path: AbsolutePath) => FormPageState | null;\n setPages: (pages: ResolvedFormPageObject[]) => void;\n setActivePage: (activePage: string | Path | null) => void;\n updateActivePage: (oldActivePageIndex: number) => void;\n registerPageState: (path: AbsolutePath, state: FormPageState) => void;\n setPageHeaderHeight: (path: AbsolutePath, height: number | null) => void;\n}\n\n/** Form pages store. */\nexport type FormPagesStore = ReturnType<typeof useCreateFormPagesContext>;\n\n/** Form pages context. */\nexport const FormPagesContext = createContext<FormPagesContextValue | null>(\n null,\n);\n\n/** Options used to create the form pages context. */\nexport interface UseCreateFormPagesContextOptions\n extends Pick<\n FormPagesProps,\n \"defaultActivePage\" | \"activePage\" | \"onActivePageChange\"\n > {\n basePath: AbsolutePath;\n resolvedPages: ResolvedFormPageObject[];\n}\n\n/** Hook used to create the form pages context. */\nexport function useCreateFormPagesContext({\n basePath,\n resolvedPages,\n defaultActivePage,\n activePage,\n onActivePageChange,\n}: UseCreateFormPagesContextOptions) {\n const setLatestInteraction = useSetLatestInteraction();\n const { activePath, onActivePathChange } = useActivePathContext();\n activePage ??= activePath;\n const latest = useLatestValues({\n printing: usePrinting(),\n onActivePathChange,\n onActivePageChange,\n });\n\n const store = useConstant(() =>\n createStore<FormPagesState>()(\n subscribeWithSelector((set, get) => ({\n pages: resolvedPages,\n activePage:\n activePage === undefined\n ? defaultActivePage == null\n ? null\n : basePath.resolve(defaultActivePage)\n : activePage === null\n ? null\n : basePath.resolve(activePage),\n activePageIndex: computed(\n () => [get().pages, get().activePage],\n (pages, activePage) =>\n activePage === null\n ? -1\n : pages.findIndex((page) => page.path.equals(activePage)),\n ),\n pageStates: [{}],\n pageHeaderHeights: [new Map()],\n navigationSelectHeight: 0,\n actions: {\n getPageState: (path) => get().pageStates[0][path.toString()] ?? null,\n setPages: (pages) => {\n const oldActivePageIndex = get().activePageIndex();\n const newPageStates: Record<string, FormPageState | null> = {};\n for (const page of pages) {\n newPageStates[page.path.toString()] = get().actions.getPageState(\n page.path,\n );\n }\n set({ pages, pageStates: [newPageStates] });\n get().actions.updateActivePage(oldActivePageIndex);\n },\n setActivePage: (path: string | Path | null) => {\n if (latest.printing) {\n return;\n }\n\n const newActivePage =\n path === null || path instanceof AbsolutePath\n ? path\n : new AbsolutePath(path);\n const oldActivePage = get().activePage;\n if (!oldActivePage?.equals(newActivePage)) {\n startTransition(() => {\n set({ activePage: newActivePage });\n if (newActivePage != null) {\n setLatestInteraction(newActivePage);\n }\n latest.onActivePathChange(newActivePage);\n latest.onActivePageChange?.(newActivePage);\n });\n }\n },\n updateActivePage: (oldActivePageIndex: number) => {\n if (\n latest.printing ||\n (get().activePage !== null &&\n get().pages.some((page) => page.path.equals(get().activePage)))\n ) {\n return;\n }\n\n get().actions.setActivePage(\n get().pages[\n Math.max(\n 0,\n Math.min(oldActivePageIndex, get().pages.length - 1),\n )\n ]?.path ?? null,\n );\n },\n registerPageState: (path, state) => {\n const oldActivePageIndex = get().activePageIndex();\n const pageStates = get().pageStates[0];\n pageStates[path.toString()] = state;\n set({ pageStates: [pageStates] });\n get().actions.updateActivePage(oldActivePageIndex);\n },\n setPageHeaderHeight: (path, height) => {\n if (latest.printing) {\n return;\n }\n\n const {\n pageHeaderHeights: [pageHeaderHeights],\n } = get();\n if (height != null) {\n pageHeaderHeights.set(path.toString(), height);\n } else {\n pageHeaderHeights.delete(path.toString());\n }\n set({ pageHeaderHeights: [pageHeaderHeights] });\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.getState().actions.setPages(resolvedPages);\n if (activePage !== undefined) {\n const { pages, activePage: oldActivePage } = store.getState();\n store.getState().actions.setActivePage(\n mostSpecificPath(\n activePage === null ? null : basePath.resolve(activePage),\n pages.map((page) => page.path),\n oldActivePage,\n ) ?? null,\n );\n }\n }, [resolvedPages, activePage, basePath, store]);\n\n // Set (possibly new) active page when focused path changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const { pages, activePage, actions } = store.getState();\n actions.setActivePage(\n mostSpecificPath(\n focusedPath,\n pages.map((page) => page.path),\n activePage,\n ) ?? null,\n );\n },\n [store],\n ),\n );\n\n return store;\n}\n\nexport function useFormPagesContext(): FormPagesContextValue {\n const formPagesContext = useContext(FormPagesContext);\n if (!formPagesContext) {\n throw new Error(\"Form pages context not in scope.\");\n }\n return formPagesContext;\n}\n\nexport function useFormPageState<T>(\n path: AbsolutePath,\n selector: (state: FormPageState | null) => T,\n): T {\n return useStore(useFormPagesContext(), (state) =>\n selector(state.actions.getPageState(path)),\n );\n}\n","import { faCircleQuestion } from \"@fortawesome/free-solid-svg-icons\";\nimport { useCurrentPath } from \"@ostack.tech/kform-react\";\nimport {\n boolDataAttr,\n controlStatusToAccent,\n cx,\n IconButton,\n Popover,\n PopoverContent,\n PopoverTrigger,\n Stack,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useIssuesDisplayMode } from \"../FormApp\";\nimport { IssueMessages } from \"../IssueMessages\";\nimport { IssuesPopover } from \"../IssuesPopover\";\nimport type { FormPageProps } from \"./FormPage.tsx\";\nimport { useFormPageState } from \"./FormPagesContext.ts\";\n\n/** Properties of the form page header. */\nexport interface FormPageHeaderProps\n extends ComponentPropsWithoutRef<\"div\">,\n Pick<\n FormPageProps,\n | \"helperText\"\n | \"helperButtonLabel\"\n | \"ownIssueMessages\"\n | \"codeProps\"\n | \"titleProps\"\n | \"headerPopoverContainerProps\"\n | \"issuesPopoverProps\"\n | \"issueMessagesProps\"\n | \"helperButtonProps\"\n | \"helperPopoverProps\"\n | \"helperPopoverContentProps\"\n > {}\n\n/** Form page header. */\nexport const FormPageHeader = forwardRef<\n ComponentRef<\"div\">,\n FormPageHeaderProps\n>(function FormPageHeader(\n {\n helperText,\n helperButtonLabel,\n ownIssueMessages,\n codeProps,\n titleProps,\n headerPopoverContainerProps,\n issuesPopoverProps,\n issueMessagesProps,\n helperButtonProps,\n helperPopoverProps,\n helperPopoverContentProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const printing = usePrinting();\n const currentPath = useCurrentPath();\n const issuesDisplayMode = useIssuesDisplayMode();\n\n const deferredIssuesToDisplay =\n useFormPageState(\n currentPath,\n useShallow(\n (state) =>\n (!printing &&\n issuesDisplayMode === \"inline\" &&\n state?.deferredIssuesToDisplay) ||\n [],\n ),\n ) ?? [];\n const deferredDisplayStatus = useFormPageState(currentPath, (state) =>\n printing ? undefined : state?.deferredDisplayStatus,\n );\n const code = useFormPageState(currentPath, (state) => state?.code);\n const title = useFormPageState(currentPath, (state) => state?.title);\n\n return (\n <div\n className={cx(prefix(\"form-pages__page-header\"), className)}\n {...otherProps}\n data-has-popovers={boolDataAttr(\n helperText != null || deferredIssuesToDisplay.length > 0,\n )}\n ref={forwardedRef}\n >\n {/* Form page code */}\n <div\n {...codeProps}\n className={cx(prefix(\"form-pages__page-code\"), codeProps?.className)}\n data-status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-accent={controlStatusToAccent(\n displayStatusToControlStatus(deferredDisplayStatus),\n )}\n >\n {code}\n </div>\n\n {/* Form page title */}\n <h2\n {...titleProps}\n className={cx(prefix(\"form-pages__page-title\"), titleProps?.className)}\n >\n {title}\n </h2>\n\n {/* Form page issues */}\n {!printing && (\n <Stack\n direction=\"row\"\n gap={0}\n {...headerPopoverContainerProps}\n className={cx(\n prefix(\"form-pages__page-header-popovers\"),\n headerPopoverContainerProps?.className,\n )}\n >\n {issuesDisplayMode === \"inline\" && (\n <IssuesPopover\n side=\"bottom\"\n {...issuesPopoverProps}\n iconButtonProps={{\n className: cx(\n prefix(\"form-pages__page-issues-popover-button\"),\n issuesPopoverProps?.iconButtonProps?.className,\n ),\n ...issuesPopoverProps?.iconButtonProps,\n }}\n >\n <IssueMessages\n issues={deferredIssuesToDisplay}\n messages={ownIssueMessages}\n {...issueMessagesProps}\n />\n </IssuesPopover>\n )}\n\n {/* Form page helper text */}\n {helperText && (\n <Popover modal={false} {...helperPopoverProps}>\n <PopoverTrigger>\n <IconButton\n circle\n color=\"primary\"\n variant=\"ghost\"\n icon={faCircleQuestion}\n label={helperButtonLabel ?? \"\"}\n {...helperButtonProps}\n tooltipProps={{\n side: \"bottom\",\n ...helperButtonProps?.tooltipProps,\n }}\n className={cx(\n prefix(\"form-pages__page-helper-button\"),\n helperButtonProps?.className,\n )}\n />\n </PopoverTrigger>\n\n <PopoverContent\n {...helperPopoverContentProps}\n className={cx(\n prefix(\"form-pages__page-helper-popover\"),\n helperPopoverContentProps?.className,\n )}\n >\n {helperText}\n </PopoverContent>\n </Popover>\n )}\n </Stack>\n )}\n </div>\n );\n});\n","import { CurrentPath, useResolvedPath } from \"@ostack.tech/kform-react\";\nimport {\n Container,\n cx,\n DocumentTitle,\n ErrorBoundary,\n type IconButton,\n type Popover,\n type PopoverContent,\n Spinner,\n type Stack,\n useCombinedRef,\n useMeasure,\n usePrinting,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n Suspense,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport {\n FormAppIssueMessages,\n FormAppStatus,\n useFormAppElement,\n} from \"../FormApp\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\nimport type { IssuesPopover } from \"../IssuesPopover\";\nimport { FormPageHeader } from \"./FormPageHeader.tsx\";\nimport type { FormPageObject } from \"./FormPages.tsx\";\nimport { useFormPagesContext, useFormPageState } from \"./FormPagesContext.ts\";\n\n/** Properties of the form page component. */\nexport interface FormPageProps\n extends FormPageObject,\n Omit<ComponentPropsWithoutRef<\"div\">, \"title\" | \"children\"> {\n /** Sets the form page as disabled. */\n disabled?: boolean;\n /** Sets the form page as read-only. */\n readOnly?: boolean;\n /** Form page helper text, displayed as a popover triggered by an icon button. */\n helperText?: ReactNode;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their code).\n *\n * Provided paths are relative to the form page's path and may contain\n * wildcards, which will have a lower priority when matched against.\n *\n * These messages are used by the `IssueMessages` component.\n *\n * **Note:** Changes to `issueMessages` are handled correctly, but are not\n * efficient. Please make sure that the identity of the provided value doesn't\n * change at every render.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /**\n * Issue messages of the form page itself.\n *\n * These messages can also be provided via the `issueMessages` property using\n * a path of \"`.`\".\n */\n ownIssueMessages?: IssueMessagesByCode;\n /** Properties to pass to the header element. */\n headerProps?: ComponentPropsWithRef<\"div\">;\n /** Label of the helper button announced to assistive technologies. */\n helperButtonLabel?: string;\n /** Properties to pass to the code element. */\n codeProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the title element. */\n titleProps?: ComponentPropsWithRef<\"h2\">;\n /**\n * Properties to pass to the element containing the popover components in the\n * header.\n */\n headerPopoverContainerProps?: ComponentPropsWithRef<typeof Stack>;\n /** Properties to pass to the form page's issues popover component. */\n issuesPopoverProps?: ComponentPropsWithRef<typeof IssuesPopover>;\n /** Properties to pass to the form page's issue messages component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"messages\"\n >;\n /** Properties to pass to the content element. */\n contentProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the container component. */\n containerProps?: ComponentPropsWithRef<typeof Container>;\n /** Properties to pass to the `ErrorBoundary` component. */\n errorBoundaryProps?: ComponentPropsWithRef<typeof ErrorBoundary>;\n /** Properties to pass to the helper button component. */\n helperButtonProps?: Omit<ComponentPropsWithRef<typeof IconButton>, \"icon\">;\n /** Properties to pass to the helper popover component. */\n helperPopoverProps?: ComponentPropsWithRef<typeof Popover>;\n /** Properties to pass to the helper popover content component. */\n helperPopoverContentProps?: ComponentPropsWithRef<typeof PopoverContent>;\n children?: ReactNode;\n}\n\n/** Form page component. */\nexport const FormPage = forwardRef<ComponentRef<\"div\">, FormPageProps>(\n function FormPage(\n {\n path,\n // `FormPageObject` props\n title: _title,\n documentTitle: _documentTitle,\n code: _code,\n issuesPanelLabel: _issuesPanelLabel,\n disabled = false,\n readOnly = false,\n className,\n helperText,\n helperButtonLabel,\n issueMessages,\n ownIssueMessages,\n headerProps,\n codeProps,\n titleProps,\n headerPopoverContainerProps,\n issuesPopoverProps,\n issueMessagesProps,\n contentProps,\n containerProps,\n errorBoundaryProps,\n helperButtonProps,\n helperPopoverProps,\n helperPopoverContentProps,\n children,\n ...otherProps\n },\n forwardedRef,\n ) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n helperButtonLabel ??= locale.FormPage.helperButtonLabel;\n const printing = usePrinting();\n\n const store = useFormPagesContext();\n const pagePath = useResolvedPath(path);\n\n const activePage = useStore(store, (state) => state.activePage);\n const shouldDisplay = useFormPageState(pagePath, (state) =>\n state?.path.equals(activePage),\n );\n const documentTitle = useFormPageState(pagePath, (state) =>\n state === null ? null : state.documentTitle,\n );\n\n if (documentTitle === undefined) {\n warnOnce(\n `FormPage: At '${pagePath.toString()}': \\`documentTitle\\` ` +\n \"should be set manually since the form page's `title` is not a string.\",\n );\n }\n\n // Keep track of the page header's height\n const [headerEl, setHeaderEl] = useState<HTMLDivElement | null>(null);\n useMeasure(\n headerEl,\n useCallback(\n (measurement) => {\n store\n .getState()\n .actions.setPageHeaderHeight(pagePath, measurement?.height ?? null);\n },\n [pagePath, store],\n ),\n );\n\n // Scroll to the top of the form app whenever we first change into a page\n const formAppEl = useFormAppElement();\n const isFirstDisplay = useRef(true);\n useEffect(() => {\n if (shouldDisplay && !printing && isFirstDisplay.current) {\n formAppEl.scrollIntoView(true);\n isFirstDisplay.current = false;\n return () => {\n isFirstDisplay.current = true;\n };\n }\n }, [formAppEl, printing, shouldDisplay]);\n\n const combinedHeaderRef = useCombinedRef(setHeaderEl, headerProps?.ref);\n return shouldDisplay || printing ? (\n <CurrentPath path={pagePath}>\n <DocumentTitle\n title={printing ? undefined : (documentTitle ?? undefined)}\n >\n <div\n className={cx(prefix(\"form-pages__page\"), className)}\n {...otherProps}\n ref={forwardedRef}\n >\n <FormAppStatus disabled={disabled} readOnly={readOnly}>\n <FormAppIssueMessages issueMessages={issueMessages}>\n <FormPageHeader\n helperText={helperText}\n helperButtonLabel={helperButtonLabel}\n ownIssueMessages={ownIssueMessages}\n codeProps={codeProps}\n titleProps={titleProps}\n headerPopoverContainerProps={headerPopoverContainerProps}\n issuesPopoverProps={issuesPopoverProps}\n issueMessagesProps={issueMessagesProps}\n helperButtonProps={helperButtonProps}\n helperPopoverProps={helperPopoverProps}\n helperPopoverContentProps={helperPopoverContentProps}\n {...headerProps}\n ref={combinedHeaderRef}\n />\n\n <div\n {...contentProps}\n className={cx(\n prefix(\"form-pages__page-content\"),\n contentProps?.className,\n )}\n >\n <Container fluid=\"md\" gutter={0} {...containerProps}>\n <ErrorBoundary {...errorBoundaryProps}>\n <Suspense\n fallback={<Spinner size=\"xl\" color=\"primary\" />}\n >\n {children}\n </Suspense>\n </ErrorBoundary>\n </Container>\n </div>\n </FormAppIssueMessages>\n </FormAppStatus>\n </div>\n </DocumentTitle>\n </CurrentPath>\n ) : null;\n },\n);\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { CurrentPath, useController } from \"@ostack.tech/kform-react\";\nimport { usePrinting, useStartPrintingTask } from \"@ostack.tech/ui\";\nimport { useDeferredValue, useEffect } from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedFormPageObject,\n useFormPagesContext,\n} from \"./FormPagesContext.ts\";\n\n/** Properties of the `FormPageRegistrar` component. */\nexport interface FormPageRegistrarProps extends ResolvedFormPageObject {}\n\n/** Component used to register a form page. */\nexport function FormPageRegistrar({\n path,\n title,\n documentTitle,\n code,\n issuesPanelLabel,\n}: FormPageRegistrarProps) {\n const store = useFormPagesContext();\n\n const printing = usePrinting();\n const finishPrintingTask = useStartPrintingTask();\n const controller = useController(\n path.append(AbsolutePathFragment.RecursiveWildcard),\n { enabled: !useFormIsLoading(), onInitialized: finishPrintingTask },\n );\n const absolutePath = controller.usePath();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n const value = controller.useValue();\n const deferredValue = useDeferredValue(value);\n const relevantValue = printing ? value : deferredValue;\n const deferredIssuesToDisplay = useDeferredValue(\n controller.useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n const actualTitle =\n typeof title === \"function\"\n ? relevantValue === undefined\n ? null\n : title(relevantValue)\n : title;\n const actualDocumentTitle =\n typeof documentTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : documentTitle(relevantValue)\n : documentTitle === undefined\n ? actualTitle === null || typeof actualTitle === \"string\"\n ? actualTitle\n : undefined\n : documentTitle;\n\n useEffect(() => {\n const { registerPageState } = store.getState().actions;\n registerPageState(absolutePath, {\n exists,\n path: absolutePath,\n deferredIssuesToDisplay,\n deferredDisplayStatus,\n title: actualTitle,\n documentTitle: actualDocumentTitle,\n code,\n });\n }, [\n absolutePath,\n actualDocumentTitle,\n actualTitle,\n code,\n deferredDisplayStatus,\n deferredIssuesToDisplay,\n exists,\n store,\n title,\n ]);\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>\n {typeof issuesPanelLabel === \"function\"\n ? deferredValue === undefined\n ? null\n : issuesPanelLabel(deferredValue)\n : issuesPanelLabel || actualTitle}\n </CurrentPath>,\n );\n\n return null;\n}\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n Path,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n useFormManager,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport {\n cx,\n useCombinedRef,\n useCssVars,\n useMediaBreakpointUp,\n} from \"@ostack.tech/ui\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormPage, type FormPageProps } from \"./FormPage.tsx\";\nimport { FormPageRegistrar } from \"./FormPageRegistrar.tsx\";\nimport {\n FormPagesContext,\n useCreateFormPagesContext,\n} from \"./FormPagesContext.ts\";\n\n/** Properties of the form page component. */\nexport interface FormPagesProps extends ComponentPropsWithoutRef<\"div\"> {\n /** Base path for all declared form pages. */\n path?: string | Path;\n /**\n * List of all form pages. When not provided, the list of pages is obtained\n * from the direct children `FormPage` components.\n */\n pages?: FormPageObject[];\n /** Default active form page. */\n defaultActivePage?: string | Path;\n /** Controlled active form page. */\n activePage?: string | Path;\n /**\n * Function called whenever the active form page changes.\n *\n * @param activePagePath Path of the new active form page.\n */\n onActivePageChange?: (activePagePath: AbsolutePath | null) => void;\n children?: ReactNode;\n}\n\n/** Object representation of a form page. */\nexport interface FormPageObject<T = any> {\n /** Form page path. */\n path?: string | Path;\n /** Form page's title */\n title?: ReactNode | ((value: T) => ReactNode);\n /**\n * Title of the form page as a string to display in the document's title.\n *\n * Defaults to `title` when it is a string. A warning is printed if `title` is\n * not a string and `documentTitle` is not provided.\n */\n documentTitle?: string | null | ((value: T) => string | null);\n /** Form page's code. */\n code?: ReactNode;\n /** Form page's label in the issues panel. The `title` is used by default. */\n issuesPanelLabel?: ReactNode | ((value: T) => ReactNode);\n}\n\n/** Root component used to render form pages. */\nexport const FormPages = forwardRef<ComponentRef<\"div\">, FormPagesProps>(\n function FormPages(\n {\n path,\n pages,\n defaultActivePage,\n activePage,\n onActivePageChange,\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n ) {\n const prefix = usePrefix();\n const { cssVarName } = useCssVars({ prefix });\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n\n pages ??= Children.toArray(children)\n .filter(\n (child): child is ReactElement<FormPageProps, typeof FormPage> =>\n isValidElement(child) && child.type === FormPage,\n )\n .map((child) => ({\n path: child.props.path,\n title: child.props.title,\n documentTitle: child.props.documentTitle,\n code: child.props.code,\n issuesPanelLabel: child.props.issuesPanelLabel,\n }));\n\n // Provided pages but with absolute paths\n const resolvedPages = useMemo(\n () =>\n pages.map((page) => ({\n ...page,\n path: absolutePath.resolve(page.path ?? Path.CURRENT),\n })),\n [absolutePath, pages],\n );\n\n // Refuse non-existent paths\n if (!formManager.isValidPath(absolutePath)) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form pages base path must only contain ids.\");\n }\n // Validate form page paths\n for (const page of resolvedPages) {\n // Refuse non-existent paths\n if (!formManager.isValidPath(page.path)) {\n throw new Error(`Invalid path: '${page.path.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n page.path.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form page path must only contain ids.\");\n }\n }\n\n const store = useCreateFormPagesContext({\n basePath: absolutePath,\n resolvedPages,\n defaultActivePage,\n activePage,\n onActivePageChange,\n });\n\n const formPagesRef = useRef<HTMLDivElement | null>(null);\n\n // Active page header height\n useEffect(\n () =>\n store.subscribe(\n ({ activePage, pageHeaderHeights: [pageHeaderHeights] }) =>\n (activePage && pageHeaderHeights.get(activePage.toString())) ?? 0,\n (height) =>\n formPagesRef.current?.style.setProperty(\n cssVarName(\"form-pages-page-header-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, prefix, store],\n );\n\n // Navigation select height\n useEffect(\n () =>\n store.subscribe(\n (state) => state.navigationSelectHeight,\n (height) =>\n formPagesRef.current?.style.setProperty(\n cssVarName(\"form-pages-navigation-select-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, prefix, store],\n );\n\n const combinedFormPagesRef = useCombinedRef(formPagesRef, forwardedRef);\n return (\n <CurrentPath path={absolutePath}>\n <FormPagesContext.Provider value={store}>\n {resolvedPages.map((page) => (\n <FormPageRegistrar key={page.path.toString()} {...page} />\n ))}\n\n <div\n className={cx(prefix(\"form-pages\"), className)}\n data-navigation-mode={isLargeScreen ? \"sidebar\" : \"select\"}\n {...otherProps}\n ref={combinedFormPagesRef}\n >\n {children}\n </div>\n </FormPagesContext.Provider>\n </CurrentPath>\n );\n },\n);\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport { controlStatusToAccent, Option } from \"@ostack.tech/ui\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useFormPageState } from \"./FormPagesContext.ts\";\n\ninterface FormPagesSelectOptionProps {\n path: AbsolutePath;\n}\n\nexport function FormPagesSelectOption({ path }: FormPagesSelectOptionProps) {\n const prefix = usePrefix();\n const disabled = useFormPageState(path, (state) => !state?.exists);\n const deferredDisplayStatus = useFormPageState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const code = useFormPageState(path, (state) => state?.code);\n const title = useFormPageState(path, (state) => state?.title);\n const controlStatus = displayStatusToControlStatus(deferredDisplayStatus);\n const accent = controlStatusToAccent(controlStatus, \"primary\");\n\n return (\n <CurrentPath path={path}>\n <Option\n value={path.toString()}\n keywords={[\n ...(typeof code === \"string\" ? [code] : []),\n ...(typeof title === \"string\" ? [title] : []),\n ]}\n className={prefix(\"form-pages__select-option\")}\n color={accent}\n disabled={disabled}\n iconProps={{\n className: prefix(\"form-pages__select-option-indicator\"),\n }}\n >\n <span\n className={prefix(\"form-pages__select-option-code\")}\n data-status={controlStatus}\n data-accent={accent}\n >\n {code}\n </span>\n {title}\n </Option>\n </CurrentPath>\n );\n}\n","import { AbsolutePath } from \"@ostack.tech/kform\";\nimport { cx, Select, useCombinedRef, useMeasure } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormPagesContext } from \"./FormPagesContext.ts\";\nimport { FormPagesSelectOption } from \"./FormPagesSelectOption.tsx\";\n\n/** Properties of the form pages select component. */\nexport interface FormPagesSelectProps\n extends Omit<\n ComponentPropsWithoutRef<typeof Select>,\n \"multiple\" | \"defaultValue\" | \"value\" | \"onValueChange\" | \"showClearButton\"\n > {}\n\n/** Select component allowing the navigation between form pages. */\nexport const FormPagesSelect = forwardRef<\n ComponentRef<typeof Select>,\n FormPagesSelectProps\n>(function FormPagesSelect(\n {\n rootProps,\n containerProps,\n valueProps,\n arrowProps,\n popoverProps,\n commandMenuProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const store = useFormPagesContext();\n const activePage = useStore(store, (state) => state.activePage);\n\n // Keep track of the select root's height\n const [selectRootEl, setSelectRootEl] = useState<HTMLDivElement | null>(null);\n useMeasure(\n selectRootEl,\n useCallback(\n (measurement) => {\n store.setState({ navigationSelectHeight: measurement?.height ?? 0 });\n },\n [store],\n ),\n );\n\n const handleValueChange = useCallback(\n (value: string) =>\n value && store.getState().actions.setActivePage(new AbsolutePath(value)),\n [store],\n );\n\n const pages = useStore(store, (state) => state.pages);\n return (\n <Select\n className={cx(prefix(\"form-pages__select\"), className)}\n value={activePage?.toString() ?? \"\"}\n onValueChange={handleValueChange}\n showClearButton={false}\n rootProps={{\n ...rootProps,\n ref: useCombinedRef(\n setSelectRootEl as (el: HTMLDivElement) => void,\n rootProps?.ref,\n ),\n }}\n containerProps={{\n ...containerProps,\n className: cx(\n prefix(\"form-pages__select-container\"),\n containerProps?.className,\n ),\n }}\n valueProps={{\n ...valueProps,\n className: cx(\n prefix(\"form-pages__select-value\"),\n valueProps?.className,\n ),\n }}\n arrowProps={{\n ...arrowProps,\n className: cx(\n prefix(\"form-pages__select-arrow\"),\n arrowProps?.className,\n ),\n }}\n popoverProps={{\n ...popoverProps,\n className: cx(\n prefix(\"form-pages__select-popover\"),\n popoverProps?.className,\n ),\n }}\n commandMenuProps={{ variant: \"subtle\", ...commandMenuProps }}\n {...otherProps}\n ref={forwardedRef}\n >\n {pages.map((page) => (\n <FormPagesSelectOption key={page.path.toString()} path={page.path} />\n ))}\n </Select>\n );\n});\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport {\n boolDataAttr,\n controlStatusToAccent,\n MenuListItem,\n} from \"@ostack.tech/ui\";\nimport { useCallback, useRef } from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { visiblyFocus } from \"../../utils/useControlAutofocus.ts\";\nimport { useIssuesDisplayMode, useOnPathFocus } from \"../FormApp\";\nimport { useResetFocus } from \"../FormApp/FormAppContext.ts\";\nimport { useFormPagesContext, useFormPageState } from \"./FormPagesContext.ts\";\n\ninterface FormPageSidebarItemProps {\n path: AbsolutePath;\n}\n\nexport function FormPageSidebarItem({ path }: FormPageSidebarItemProps) {\n const prefix = usePrefix();\n const store = useFormPagesContext();\n const activePage = useStore(store, (state) => state.activePage);\n\n const handleClick = () => store.getState().actions.setActivePage(path);\n\n const disabled = useFormPageState(path, (state) => !state?.exists);\n const deferredDisplayStatus = useFormPageState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const code = useFormPageState(path, (state) => state?.code);\n const title = useFormPageState(path, (state) => state?.title);\n\n const issuesDisplayMode = useIssuesDisplayMode();\n const itemActionRef = useRef<HTMLButtonElement | null>(null);\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath: AbsolutePath) => {\n if (itemActionRef.current && path.equals(focusedPath)) {\n // In inline mode the issues popover should get focused instead\n if (issuesDisplayMode === \"panel\") {\n visiblyFocus(itemActionRef.current);\n }\n // Let the form page be opened before resetting focus\n setTimeout(() => resetFocus());\n }\n },\n [issuesDisplayMode, path, resetFocus],\n ),\n );\n\n const isSelected = activePage?.equals(path);\n return (\n <MenuListItem\n className={prefix(\"form-pages__sidebar-item\")}\n selected={isSelected}\n disabled={disabled}\n onSelect={handleClick}\n color=\"primary\"\n contentProps={{ className: prefix(\"form-pages__sidebar-item-content\") }}\n actionProps={{ ref: itemActionRef }}\n >\n <CurrentPath path={path}>\n <span\n className={prefix(\"form-pages__sidebar-item-code\")}\n data-selected={boolDataAttr(isSelected)}\n data-status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-accent={controlStatusToAccent(\n displayStatusToControlStatus(deferredDisplayStatus),\n )}\n >\n {code}\n </span>\n {title}\n </CurrentPath>\n </MenuListItem>\n );\n}\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { useFormContext } from \"@ostack.tech/kform-react\";\nimport { cx, MenuList, useCombinedRef, useMeasure } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useSetLeftSidebarWidth } from \"../FormApp\";\nimport { useFormPagesContext } from \"./FormPagesContext.ts\";\nimport { FormPageSidebarItem } from \"./FormPageSidebarItem.tsx\";\n\n/** Properties of the form pages sidebar component. */\nexport interface FormPagesSidebarProps\n extends ComponentPropsWithoutRef<\"aside\"> {}\n\n/** Sidebar component allowing the navigation between form pages. */\nexport const FormPagesSidebar = forwardRef<\n ComponentRef<\"aside\">,\n FormPagesSidebarProps\n>(function FormPagesSidebar({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n const store = useFormPagesContext();\n const { currentPath } = useFormContext();\n const activePage = useStore(store, (state) => state.activePage);\n const setLeftSidebarWidth = useSetLeftSidebarWidth();\n\n // Inform form app of \"active\" form pages navigation components (affect the\n // positioning of the issues panel when the sidebar is visible)\n const [sidebarEl, setSidebarEl] = useState<HTMLElement | null>(null);\n useMeasure(\n sidebarEl,\n useCallback(\n (measurement) => {\n if (\n activePage &&\n currentPath\n .append(AbsolutePathFragment.RecursiveWildcard)\n .contains(activePage)\n ) {\n setLeftSidebarWidth(measurement?.width);\n }\n },\n [activePage, currentPath, setLeftSidebarWidth],\n ),\n );\n\n const pages = useStore(store, (state) => state.pages);\n const combinedSidebarRef = useCombinedRef(setSidebarEl, forwardedRef);\n return (\n <aside\n className={cx(prefix(\"form-pages__sidebar\"), className)}\n {...otherProps}\n ref={combinedSidebarRef}\n >\n <MenuList>\n {pages.map((page) => (\n <FormPageSidebarItem key={page.path.toString()} path={page.path} />\n ))}\n </MenuList>\n </aside>\n );\n});\n","import { cx, useMediaBreakpointUp, usePrintClassNames } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormPagesSelect } from \"./FormPagesSelect.tsx\";\nimport { FormPagesSidebar } from \"./FormPagesSidebar.tsx\";\n\n/** Properties of the form pages navigation component. */\nexport interface FormPagesNavigationProps\n extends ComponentPropsWithoutRef<\"nav\"> {\n /** Properties to pass to the sidebar component. */\n sidebarProps?: ComponentPropsWithRef<typeof FormPagesSidebar>;\n /** Properties to pass to the select component. */\n selectProps?: ComponentPropsWithRef<typeof FormPagesSelect>;\n}\n\n/** Component allowing the navigation between form pages. */\nexport const FormPagesNavigation = forwardRef<\n ComponentRef<\"nav\">,\n FormPagesNavigationProps\n>(function FormPagesNavigation(\n {\n sidebarProps,\n selectProps,\n className,\n \"aria-label\": ariaLabel,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n ariaLabel ??= locale.FormPagesNavigation[\"aria-label\"];\n const { printHidden } = usePrintClassNames();\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n\n return (\n <nav\n className={cx(prefix(\"form-pages__navigation\"), printHidden, className)}\n data-navigation-mode={isLargeScreen ? \"sidebar\" : \"select\"}\n aria-label={ariaLabel}\n {...otherProps}\n ref={forwardedRef}\n >\n {isLargeScreen ? (\n <FormPagesSidebar {...sidebarProps} />\n ) : (\n <FormPagesSelect {...selectProps} />\n )}\n </nav>\n );\n});\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n type DisplayStatus,\n type FormManager,\n} from \"@ostack.tech/kform\";\nimport { useConstant, useLatestValues, usePrinting } from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { useActivePathContext } from \"../../providers/ActivePathProvider\";\nimport { mostSpecificPath } from \"../../utils/mostSpecificPath.ts\";\nimport { useFocus, useOnPathFocus } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport type { FormStepObject, FormStepperProps } from \"./FormStepper.tsx\";\n\n/** Value of the form stepper context. */\nexport type FormStepperContextValue = FormStepperStore;\n\n/** Resolved form step object. */\nexport interface ResolvedFormStepObject extends FormStepObject {\n path: AbsolutePath;\n index: number;\n}\n\n/** Form step state. */\nexport interface FormStepState {\n path: AbsolutePath;\n index: number;\n exists: boolean;\n deferredDisplayStatus: DisplayStatus | undefined;\n title?: ReactNode;\n documentTitle?: string | null;\n}\n\n/** State of the form stepper. */\nexport interface FormStepperState {\n steps: ResolvedFormStepObject[];\n activeStep: ResolvedFormStepObject | null;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new map\n // instances\n stepStates: [Record<string, FormStepState | null>];\n actions: FormStepperActions;\n}\n\n/** Actions of the form stepper. */\nexport interface FormStepperActions {\n getStepState: (path: AbsolutePath) => FormStepState | null;\n setSteps: (steps: ResolvedFormStepObject[]) => void;\n setActiveStep: (\n activeStep: ResolvedFormStepObject | null,\n callListener?: boolean,\n ) => void;\n updateActiveStep: () => void;\n registerStepState: (path: AbsolutePath, state: FormStepState) => void;\n goToStep: (index: number) => Promise<void>;\n}\n\n/** Form stepper store. */\nexport type FormStepperStore = ReturnType<typeof useCreateFormStepperContext>;\n\n/** Form stepper context. */\nexport const FormStepperContext = createContext<FormStepperContextValue | null>(\n null,\n);\n\n/** Options used to create the form stepper context. */\nexport interface UseCreateFormStepperContextOptions\n extends Pick<\n FormStepperProps,\n | \"defaultActiveStep\"\n | \"activeStep\"\n | \"onActiveStepChange\"\n | \"onStepValidation\"\n | \"skipStepValidationOnForwardNavigation\"\n | \"allowForwardNavigationOnError\"\n | \"preventFocusOnError\"\n > {\n formManager: FormManager;\n basePath: AbsolutePath;\n resolvedSteps: ResolvedFormStepObject[];\n}\n\n/** Hook used to create the form stepper context. */\nexport function useCreateFormStepperContext({\n formManager,\n basePath,\n resolvedSteps,\n defaultActiveStep,\n activeStep,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n}: UseCreateFormStepperContextOptions) {\n const focus = useFocus();\n const setLatestInteraction = useSetLatestInteraction();\n const { activePath, onActivePathChange } = useActivePathContext();\n activeStep ??= activePath;\n const latest = useLatestValues({\n printing: usePrinting(),\n formManager,\n onActivePathChange,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n });\n\n const store = useConstant(() =>\n createStore<FormStepperState>()(\n subscribeWithSelector((set, get) => ({\n steps: resolvedSteps,\n activeStep:\n activeStep === undefined\n ? defaultActiveStep == null\n ? null\n : (resolvedSteps.find((data) =>\n data.path.equals(basePath.resolve(defaultActiveStep)),\n ) ?? null)\n : activeStep === null\n ? null\n : (resolvedSteps.find((data) =>\n data.path.equals(basePath.resolve(activeStep)),\n ) ?? null),\n stepStates: [{}],\n actions: {\n getStepState: (path) => get().stepStates[0][path.toString()] ?? null,\n setSteps: (steps) => {\n const newStepStates: Record<string, FormStepState | null> = {};\n for (const step of steps) {\n newStepStates[step.path.toString()] = get().actions.getStepState(\n step.path,\n );\n }\n set({\n steps,\n stepStates: [newStepStates],\n });\n get().actions.updateActiveStep();\n },\n setActiveStep: (\n step: ResolvedFormStepObject | null,\n callListener = true,\n ) => {\n if (latest.printing) {\n return;\n }\n\n const oldActiveStep = get().activeStep;\n if (\n !oldActiveStep?.path.equals(step?.path) ||\n oldActiveStep?.index !== step?.index\n ) {\n startTransition(() => {\n set({ activeStep: step });\n if (step != null) {\n setLatestInteraction(step.path);\n }\n latest.onActivePathChange(step?.path ?? null);\n if (callListener) {\n latest.onActiveStepChange?.(\n step?.path ?? null,\n step?.index ?? -1,\n );\n }\n });\n }\n },\n updateActiveStep: () => {\n if (\n latest.printing ||\n (get().activeStep !== null &&\n get().steps.some((step) =>\n step.path.equals(get().activeStep!.path),\n ))\n ) {\n return;\n }\n\n get().actions.setActiveStep(\n get().steps[\n Math.max(\n 0,\n Math.min(\n get().activeStep?.index ?? -1,\n get().steps.length - 1,\n ),\n )\n ] ?? null,\n );\n },\n registerStepState: (path, state) => {\n const stepStates = get().stepStates[0];\n stepStates[path.toString()] = state;\n set({ stepStates: [stepStates] });\n get().actions.updateActiveStep();\n },\n goToStep: async (newStepIndex: number) => {\n if (latest.printing) {\n return;\n }\n\n const oldActiveStep = get().activeStep;\n const newActiveStep = get().steps[newStepIndex];\n if (\n (oldActiveStep?.path != newActiveStep?.path &&\n (oldActiveStep?.path == null || newActiveStep?.path == null)) ||\n (oldActiveStep?.path != null &&\n newActiveStep?.path != null &&\n !newActiveStep.path.contains(oldActiveStep.path))\n ) {\n // Mark steps as touched and validate them prior to moving to the\n // following step (when `skipStepValidationOnForwardNavigation` is\n // not set)\n let shouldChangeActiveStep = true;\n if (\n !latest.skipStepValidationOnForwardNavigation &&\n oldActiveStep &&\n newActiveStep &&\n oldActiveStep.index < newActiveStep.index\n ) {\n const touchAndValidateStep = async (i: number) => {\n const stepPathRecursive = get().steps[i].path.append(\n AbsolutePathFragment.RecursiveWildcard,\n );\n await latest.formManager.setTouched(stepPathRecursive);\n const issues =\n await latest.formManager.validate(stepPathRecursive);\n latest.onStepValidation?.(issues);\n return issues;\n };\n\n for (\n let i = oldActiveStep.index;\n i < newActiveStep.index;\n ++i\n ) {\n // Unless `allowForwardNavigationOnError` is set, focus the first\n // error we find after validating the form, and don't allow\n // navigating further\n if (latest.allowForwardNavigationOnError) {\n void touchAndValidateStep(i);\n } else {\n const issues = await touchAndValidateStep(i);\n const firstError = issues.find(\n (issue) => issue.severity === \"error\",\n );\n if (firstError) {\n shouldChangeActiveStep = false;\n if (!latest.preventFocusOnError) {\n setTimeout(() => focus(firstError.path));\n }\n break;\n }\n }\n }\n }\n\n if (shouldChangeActiveStep) {\n get().actions.setActiveStep(newActiveStep);\n }\n }\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.getState().actions.setSteps(resolvedSteps);\n if (activeStep !== undefined) {\n const { steps, activeStep: oldActiveStep } = store.getState();\n const specificPath = mostSpecificPath(\n activeStep === null ? null : basePath.resolve(activeStep),\n steps.map((step) => step.path),\n oldActiveStep?.path ?? null,\n );\n store\n .getState()\n .actions.setActiveStep(\n steps.find((step) => step.path.equals(specificPath)) ?? null,\n false,\n );\n }\n }, [resolvedSteps, activeStep, basePath, store]);\n\n // Set (possibly new) active step when focused path changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const { steps, activeStep, actions } = store.getState();\n const specificPath = mostSpecificPath(\n focusedPath,\n steps.map((step) => step.path),\n activeStep?.path ?? null,\n );\n actions.setActiveStep(\n steps.find((step) => step.path.equals(specificPath)) ?? null,\n );\n },\n [store],\n ),\n );\n\n return store;\n}\n\nexport function useFormStepperContext(): FormStepperContextValue {\n const formStepperContext = useContext(FormStepperContext);\n if (!formStepperContext) {\n throw new Error(\"Form stepper context not in scope.\");\n }\n return formStepperContext;\n}\n\nexport function useFormStepState<T>(\n path: AbsolutePath,\n selector: (state: FormStepState | null) => T,\n): T {\n return useStore(useFormStepperContext(), (state) =>\n selector(state.actions.getStepState(path)),\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport { CurrentPath, useResolvedPath } from \"@ostack.tech/kform-react\";\nimport {\n cx,\n DocumentTitle,\n ErrorBoundary,\n Spinner,\n StepContent,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n Suspense,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormAppStatus } from \"../FormApp\";\nimport { useFormStepState } from \"./FormStepperContext.ts\";\n\n/** Properties of the form step content component. */\nexport interface FormStepContentProps\n extends Omit<\n ComponentPropsWithoutRef<typeof StepContent>,\n \"index\" | \"children\"\n > {\n /**\n * Step path. This should match the path of the step provided to\n * `FormStepper`.\n */\n path?: string | Path;\n /** Sets the step as disabled. */\n disabled?: boolean;\n /** Sets the step as read-only. */\n readOnly?: boolean;\n /** Properties to pass to the `ErrorBoundary` component. */\n errorBoundaryProps?: ComponentPropsWithRef<typeof ErrorBoundary>;\n children?: ReactNode;\n}\n\n/** Component containing the content of a form step. */\nexport const FormStepContent = forwardRef<\n ComponentRef<typeof StepContent>,\n FormStepContentProps\n>(function FormStepContent(\n {\n path,\n disabled = false,\n readOnly = false,\n errorBoundaryProps,\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const stepPath = useResolvedPath(path);\n const index = useFormStepState(stepPath, (controller) => controller?.index);\n const documentTitle = useFormStepState(stepPath, (state) =>\n state === null ? null : state.documentTitle,\n );\n\n if (documentTitle === undefined) {\n warnOnce(\n `FormStep: At '${stepPath.toString()}': \\`documentTitle\\` ` +\n \"should be set manually since the form step's `title` is not a string.\",\n );\n }\n\n return (\n index != null && (\n <CurrentPath path={stepPath}>\n <StepContent\n index={index}\n className={cx(prefix(\"form-stepper__step-content\"), className)}\n {...otherProps}\n ref={forwardedRef}\n >\n <DocumentTitle title={documentTitle ?? undefined}>\n <FormAppStatus disabled={disabled} readOnly={readOnly}>\n <ErrorBoundary {...errorBoundaryProps}>\n <Suspense fallback={<Spinner size=\"xl\" color=\"primary\" />}>\n {children}\n </Suspense>\n </ErrorBoundary>\n </FormAppStatus>\n </DocumentTitle>\n </StepContent>\n </CurrentPath>\n )\n );\n});\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport { Step } from \"@ostack.tech/ui\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useFormStepState } from \"./FormStepperContext.ts\";\n\n/** Properties of the form step component. */\nexport interface FormStepProps {\n path: AbsolutePath;\n index: number;\n}\n\n/** Form step. */\nexport function FormStep({ path, index }: FormStepProps) {\n const prefix = usePrefix();\n const deferredDisplayStatus = useFormStepState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const disabled = useFormStepState(path, (state) => !state?.exists);\n const title = useFormStepState(path, (state) => state?.title);\n\n return (\n <Step\n index={index}\n status={displayStatusToControlStatus(deferredDisplayStatus)}\n disabled={disabled}\n className={prefix(\"form-stepper__step\")}\n >\n <CurrentPath path={path}>{title}</CurrentPath>\n </Step>\n );\n}\n","import { cx, StepList } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormStep } from \"./FormStep.tsx\";\nimport { useFormStepperContext } from \"./FormStepperContext.ts\";\n\n/** Properties of the form steps sidebar component. */\nexport interface FormStepListProps\n extends ComponentPropsWithoutRef<typeof StepList> {}\n\n/** Component displaying all form steps in a list. */\nexport const FormStepList = forwardRef<\n ComponentRef<typeof StepList>,\n FormStepListProps\n>(function FormStepperSidebar({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n const steps = useStore(useFormStepperContext(), (state) => state.steps);\n\n return (\n <StepList\n className={cx(prefix(\"form-stepper__step-list\"), className)}\n {...otherProps}\n ref={forwardedRef}\n >\n {steps.map((step) => (\n <FormStep\n key={step.path.toString()}\n path={step.path}\n index={step.index}\n />\n ))}\n </StepList>\n );\n});\n","import { CurrentPath, useController } from \"@ostack.tech/kform-react\";\nimport { usePrinting } from \"@ostack.tech/ui\";\nimport { useDeferredValue, useEffect } from \"react\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedFormStepObject,\n useFormStepperContext,\n} from \"./FormStepperContext.ts\";\n\n/** Properties of the `FormStepRegistrar` component. */\nexport interface FormStepRegistrarProps extends ResolvedFormStepObject {}\n\n/** Component used to register a form step. */\nexport function FormStepRegistrar({\n index,\n path,\n title,\n documentTitle,\n issuesPanelLabel,\n}: FormStepRegistrarProps) {\n const store = useFormStepperContext();\n\n const printing = usePrinting();\n const controller = useController(path, { enabled: !useFormIsLoading() });\n const absolutePath = controller.usePath();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n const value = controller.useValue();\n const deferredValue = useDeferredValue(value);\n const relevantValue = printing ? value : deferredValue;\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n const actualTitle =\n typeof title === \"function\"\n ? relevantValue === undefined\n ? null\n : title(relevantValue)\n : title;\n const actualDocumentTitle =\n typeof documentTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : documentTitle(relevantValue)\n : documentTitle === undefined\n ? actualTitle === null || typeof actualTitle === \"string\"\n ? actualTitle\n : undefined\n : documentTitle;\n\n useEffect(() => {\n const { registerStepState } = store.getState().actions;\n registerStepState(absolutePath, {\n exists,\n path: absolutePath,\n deferredDisplayStatus,\n index,\n title: actualTitle,\n documentTitle: actualDocumentTitle,\n });\n }, [\n absolutePath,\n actualDocumentTitle,\n actualTitle,\n deferredDisplayStatus,\n exists,\n index,\n store,\n title,\n ]);\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>\n {typeof issuesPanelLabel === \"function\"\n ? deferredValue === undefined\n ? null\n : issuesPanelLabel(deferredValue)\n : issuesPanelLabel || actualTitle}\n </CurrentPath>,\n );\n\n return null;\n}\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n Path,\n type SealedLocatedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n useFormManager,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport { cx, Stepper } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport {\n FormStepperContext,\n useCreateFormStepperContext,\n} from \"./FormStepperContext.ts\";\nimport { FormStepRegistrar } from \"./FormStepRegistrar.tsx\";\n\n/** Properties of the form stepper component. */\nexport interface FormStepperProps\n extends Omit<\n ComponentPropsWithoutRef<typeof Stepper>,\n \"defaultActiveStep\" | \"activeStep\" | \"onActiveStepChange\"\n > {\n /** Base path for all declared form steps. */\n path?: string | Path;\n /** List of all form steps. */\n steps: FormStepObject[];\n /** Default active form step. */\n defaultActiveStep?: string | Path;\n /** Controlled active form step. */\n activeStep?: string | Path;\n /**\n * Function called whenever the active form step changes.\n *\n * @param activeStepPath Path of the new active form step.\n * @param activeStepIndex Index of the new active form step.\n */\n onActiveStepChange?: (\n activeStepPath: AbsolutePath | null,\n activeStepIndex: number,\n ) => void;\n /**\n * Function called when a step is touched and validated due to a navigation to\n * a following step. This function is never called when\n * `skipStepValidationOnForwardNavigation` is `true`.\n *\n * @param issues Issues present in the step.\n */\n onStepValidation?: (issues: SealedLocatedValidationIssue[]) => void;\n /**\n * Whether to skip marking a step as touched and validating it when navigating\n * to a following step.\n *\n * @default false\n */\n skipStepValidationOnForwardNavigation?: boolean;\n /**\n * Whether to allow navigation to a following step when a previous step\n * contains errors. This is always `true` when\n * `skipStepValidationOnForwardNavigation` is also `true`.\n *\n * @default false\n */\n allowForwardNavigationOnError?: boolean;\n /**\n * Whether to prevent the focus of an invalid field when a step was validated\n * and an error was found. This is always `true` if either\n * `skipStepValidationOnForwardNavigation` or `allowForwardNavigationOnError`\n * are `true`.\n *\n * @default false\n */\n preventFocusOnError?: boolean;\n}\n\n/** Object representation of a form step. */\nexport interface FormStepObject<T = any> {\n /** Form step path. */\n path?: string | Path;\n /** Form step's title. */\n title: ReactNode | ((value: T) => ReactNode);\n /**\n * Title of the form step as a string to display in the document's title.\n *\n * Defaults to `title` when it is a string. A warning is printed if `title` is\n * not a string and `documentTitle` is not provided.\n */\n documentTitle?: string | null | ((value: T) => string | null);\n /** Label of the form step in the issues panel. Uses the `title` by default. */\n issuesPanelLabel?: ReactNode | ((value: T) => ReactNode);\n}\n\n/** Root component used to render form steps. */\nexport const FormStepper = forwardRef<\n ComponentRef<typeof Stepper>,\n FormStepperProps\n>(function FormStepper(\n {\n path,\n steps,\n defaultActiveStep,\n activeStep,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n\n // Provided steps but with absolute paths and indices\n const resolvedSteps = useMemo(\n () =>\n steps.map((step, i) => ({\n ...step,\n index: i,\n path: absolutePath.resolve(step.path ?? Path.CURRENT),\n })),\n [absolutePath, steps],\n );\n\n // Refuse non-existent paths\n if (!formManager.isValidPath(absolutePath)) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form stepper base path must only contain ids.\");\n }\n // Validate form step paths\n for (const step of resolvedSteps) {\n // Refuse non-existent paths\n if (!formManager.isValidPath(step.path)) {\n throw new Error(`Invalid path: '${step.path.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n step.path.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form step path must only contain ids.\");\n }\n }\n\n const store = useCreateFormStepperContext({\n formManager,\n basePath: absolutePath,\n resolvedSteps,\n defaultActiveStep,\n activeStep,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n });\n const activeIndex = useStore(store, (state) => state.activeStep?.index ?? -1);\n const { goToStep } = useStore(store, (state) => state.actions);\n\n return (\n <CurrentPath path={absolutePath}>\n <FormStepperContext.Provider value={store}>\n {resolvedSteps.map((step) => (\n <FormStepRegistrar key={step.path.toString()} {...step} />\n ))}\n\n <Stepper\n className={cx(prefix(\"form-stepper\"), className)}\n activeStep={activeIndex}\n onActiveStepChange={goToStep}\n {...otherProps}\n ref={forwardedRef}\n />\n </FormStepperContext.Provider>\n </CurrentPath>\n );\n});\n","import type { Path, ValidationIssueData } from \"@ostack.tech/kform\";\nimport { useIssuesTracker } from \"@ostack.tech/kform-react\";\nimport { Alert } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\n\n/** Properties of the issue alert component. */\nexport interface IssueAlertProps\n extends Omit<\n ComponentPropsWithoutRef<typeof Alert>,\n \"severity\" | \"children\"\n > {\n /** Path of the value with the issue in question. */\n path?: string | Path;\n /** Code of the issue in question. */\n code: string;\n children?: ReactNode | ((issueData: ValidationIssueData) => ReactNode);\n}\n\n/** Component used to display an issue alert. */\nexport const IssueAlert = forwardRef<\n ComponentRef<typeof Alert>,\n IssueAlertProps\n>(function IssueMessage({ path, code, children, ...otherProps }, forwardedRef) {\n const { info } = useIssuesTracker(path);\n const relevantIssues = (info?.flatMap((info) => info.issues) ?? []).filter(\n (issue) => issue.code === code,\n );\n\n return (\n <>\n {relevantIssues.map((issue, i) => (\n <Alert\n {...otherProps}\n severity={issue.severity === \"error\" ? \"danger\" : \"warning\"}\n ref={forwardedRef}\n key={i}\n >\n {typeof children === \"function\"\n ? children(issue.data ?? {})\n : children}\n </Alert>\n ))}\n </>\n );\n});\n","import { useFormController } from \"@ostack.tech/kform-react\";\nimport { useCallback, useMemo } from \"react\";\n\nimport { useStartIssuesNavigation } from \"../components/FormApp\";\n\n/** Result of the {@link useFormValidator} hook. */\nexport interface FormValidatorResult {\n /**\n * Function used to validate the form.\n *\n * @returns Promise which resolves once the form has been validated.\n */\n validate: () => Promise<void>;\n}\n\n/** Hook exposing a function used to validate the form. */\nexport function useFormValidator(): FormValidatorResult {\n const startIssuesNavigation = useStartIssuesNavigation();\n const { _setState } = useFormController();\n\n const validate = useCallback(async () => {\n _setState({ validating: true } as any);\n try {\n await startIssuesNavigation();\n } finally {\n _setState({ validating: false } as any);\n }\n }, [_setState, startIssuesNavigation]);\n\n return useMemo(() => ({ validate }), [validate]);\n}\n\n/** Result of the {@link useFormIsValidating} hook. */\nexport interface FormIsValidatingResult {\n /**\n * Whether form is being validated automatically (due to validating mode being\n * set to `\"auto\"`).\n */\n validatingAutomatically: boolean;\n /**\n * Whether form is being validated manually (due to an explicit `validate`\n * call).\n */\n validatingManually: boolean;\n /** Whether form is being validated (either automatically or manually). */\n validating: boolean;\n}\n\n/** Hook exposing whether the form is currently being validated. */\nexport function useFormIsValidating(): FormIsValidatingResult {\n const validatingAutomatically =\n useFormController().useAutoValidationStatus() === \"activeRunning\";\n const validatingManually = useFormController().useState(\n (state) => (state as any).validating,\n );\n\n return useMemo(\n () => ({\n validatingAutomatically,\n validatingManually,\n validating: validatingAutomatically || validatingManually,\n }),\n [validatingAutomatically, validatingManually],\n );\n}\n","import {\n faAngleLeft,\n faAngleRight,\n faAnglesLeft,\n faAnglesRight,\n faArrowsToDot,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport type { AbsolutePath } from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport {\n CloseButton,\n combineEventHandlers,\n cx,\n IconButton,\n type IconButtonColor,\n Spinner,\n VisuallyHidden,\n} from \"@ostack.tech/ui\";\nimport { useDeferredValue } from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsValidating } from \"../../utils/useFormValidator.ts\";\nimport { useFocus } from \"../FormApp\";\nimport type { IssuesPanelProps } from \"./IssuesPanel.tsx\";\n\n/** Properties of the issues panel controls component. */\nexport interface IssuesPanelControlsProps\n extends Pick<\n IssuesPanelProps,\n | \"focusButtonLabel\"\n | \"previousIssueButtonLabel\"\n | \"nextIssueButtonLabel\"\n | \"firstIssueButtonLabel\"\n | \"lastIssueButtonLabel\"\n | \"paginationLabel\"\n | \"validatingSpinnerProps\"\n | \"paginationProps\"\n | \"focusButtonProps\"\n | \"previousIssueButtonProps\"\n | \"nextIssueButtonProps\"\n | \"firstIssueButtonProps\"\n | \"lastIssueButtonProps\"\n | \"closeButtonProps\"\n > {\n currentPagePath: AbsolutePath | null;\n currentPageIndex: number;\n currentPageController: Controller;\n nPages: number;\n goToPreviousPage: () => void;\n goToNextPage: () => void;\n goToFirstPage: () => void;\n goToLastPage: () => void;\n buttonsColor?: IconButtonColor;\n closePanel: () => void;\n}\n\n/** Controls of the issues panel. */\nexport function IssuesPanelControls({\n currentPagePath,\n nPages,\n currentPageIndex,\n currentPageController,\n goToPreviousPage,\n goToNextPage,\n goToFirstPage,\n goToLastPage,\n buttonsColor,\n closePanel,\n focusButtonLabel,\n previousIssueButtonLabel,\n nextIssueButtonLabel,\n firstIssueButtonLabel,\n lastIssueButtonLabel,\n paginationLabel,\n validatingSpinnerProps,\n paginationProps,\n focusButtonProps,\n previousIssueButtonProps,\n nextIssueButtonProps,\n firstIssueButtonProps,\n lastIssueButtonProps,\n closeButtonProps,\n}: IssuesPanelControlsProps) {\n const prefix = usePrefix();\n const { validating } = useFormIsValidating();\n const deferredValidating = useDeferredValue(validating);\n const currentPageInitialized = currentPageController.useInitialized();\n const currentPageExists = currentPageController.useExists();\n\n const focus = useFocus();\n\n return (\n <div className={prefix(\"issues-panel__controls\")}>\n {nPages > 0 && (\n <>\n {/* Validating spinner. */}\n {deferredValidating && (\n <Spinner\n {...validatingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__validating-spinner\"),\n validatingSpinnerProps?.className,\n )}\n />\n )}\n\n {/* Pagination. */}\n <div\n role=\"presentation\"\n aria-live=\"polite\"\n {...paginationProps}\n className={cx(\n prefix(\"issues-panel__pagination\"),\n paginationProps?.className,\n )}\n >\n {paginationLabel && currentPageIndex !== -1 && (\n <VisuallyHidden>\n {paginationLabel(currentPageIndex + 1, nPages)}\n </VisuallyHidden>\n )}\n <span aria-hidden=\"true\">\n {currentPageIndex === -1 ? \"-\" : currentPageIndex + 1} / {nPages}\n </span>\n </div>\n\n {/* Focus button. */}\n <IconButton\n color={buttonsColor}\n icon={faArrowsToDot}\n {...focusButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__focus\"),\n focusButtonProps?.className,\n )}\n label={focusButtonLabel ?? \"\"}\n loading={!currentPageInitialized}\n disabled={!currentPageExists}\n onClick={combineEventHandlers(focusButtonProps?.onClick, () =>\n focus(currentPagePath!),\n )}\n />\n\n {/* First issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAnglesLeft}\n {...firstIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__first\"),\n firstIssueButtonProps?.className,\n )}\n label={firstIssueButtonLabel ?? \"\"}\n disabled={firstIssueButtonProps?.disabled || currentPageIndex === 0}\n onClick={combineEventHandlers(\n firstIssueButtonProps?.onClick,\n goToFirstPage,\n )}\n />\n\n {/* Previous issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAngleLeft}\n {...previousIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__previous\"),\n previousIssueButtonProps?.className,\n )}\n label={previousIssueButtonLabel ?? \"\"}\n disabled={\n previousIssueButtonProps?.disabled || currentPageIndex === 0\n }\n onClick={combineEventHandlers(\n previousIssueButtonProps?.onClick,\n goToPreviousPage,\n )}\n />\n\n {/* Next issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAngleRight}\n {...nextIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__next\"),\n nextIssueButtonProps?.className,\n )}\n label={nextIssueButtonLabel ?? \"\"}\n disabled={\n nextIssueButtonProps?.disabled || currentPageIndex === nPages - 1\n }\n onClick={combineEventHandlers(\n nextIssueButtonProps?.onClick,\n goToNextPage,\n )}\n />\n\n {/* Last issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAnglesRight}\n {...lastIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__last\"),\n lastIssueButtonProps?.className,\n )}\n label={lastIssueButtonLabel ?? \"\"}\n disabled={\n lastIssueButtonProps?.disabled || currentPageIndex === nPages - 1\n }\n onClick={combineEventHandlers(\n lastIssueButtonProps?.onClick,\n goToLastPage,\n )}\n />\n </>\n )}\n\n {/* Close button. */}\n <CloseButton\n color={buttonsColor}\n {...closeButtonProps}\n className={cx(\n prefix(\"issues-panel__close-button\"),\n closeButtonProps?.className,\n )}\n onClick={combineEventHandlers(closeButtonProps?.onClick, closePanel, {\n checkDefaultPrevented: true,\n })}\n />\n </div>\n );\n}\n","import {\n faCircleCheck,\n faCircleExclamation,\n faTriangleExclamation,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport type { AbsolutePath, ValidationIssueSeverity } from \"@ostack.tech/kform\";\nimport {\n type Controller,\n CurrentPath,\n type IssuesTrackerResult,\n useFormManager,\n} from \"@ostack.tech/kform-react\";\nimport {\n Card,\n CardBody,\n CardHeader,\n CardTitle,\n cx,\n Icon,\n type IconButtonColor,\n setBoolDataAttr,\n Spinner,\n useCombinedRef,\n useScrollPosition,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useActiveIssuesPanelBreadcrumb, useIsRegistered } from \"../FormApp\";\nimport { IssueMessage } from \"../IssueMessage\";\nimport type { IssuesPanelProps } from \"./IssuesPanel.tsx\";\n\nexport interface IssuesPanelMessagesCardProps\n extends ComponentPropsWithoutRef<typeof Card>,\n Pick<\n IssuesPanelProps,\n | \"displayIssueCodes\"\n | \"unknownErrorMessage\"\n | \"unknownWarningMessage\"\n | \"errorsLabel\"\n | \"warningsLabel\"\n | \"noIssuesMessage\"\n | \"resolvedTitle\"\n | \"resolvedMessage\"\n | \"headerProps\"\n | \"bodyProps\"\n | \"loadingSpinnerProps\"\n | \"titleProps\"\n | \"iconProps\"\n > {\n currentPagePath: AbsolutePath | null;\n currentPageController: Controller;\n issuesTrackerResult: IssuesTrackerResult;\n currentPageIndex: number;\n renderControls: (buttonsColor?: IconButtonColor) => ReactNode;\n}\n\nexport const IssuesPanelMessagesCard = forwardRef<\n ComponentRef<typeof Card>,\n IssuesPanelMessagesCardProps\n>(function IssuesPanelMessagesCard(\n {\n currentPagePath,\n currentPageController,\n issuesTrackerResult,\n currentPageIndex,\n errorsLabel,\n warningsLabel,\n noIssuesMessage,\n resolvedTitle,\n resolvedMessage,\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n renderControls,\n headerProps,\n bodyProps,\n loadingSpinnerProps,\n titleProps,\n iconProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { initialized, info } = issuesTrackerResult;\n const nPages = info?.length ?? 0;\n const currentInfo = currentPageIndex === -1 ? null : info![currentPageIndex];\n const currentPageExists = currentPageController.useExists();\n\n // Relevant icon and colour\n const relevantIcon = initialized\n ? !currentInfo\n ? faCircleCheck\n : currentInfo.localDisplayStatus === \"error\"\n ? faCircleExclamation\n : faTriangleExclamation\n : undefined;\n const relevantColor = initialized\n ? nPages === 0\n ? \"success\"\n : !currentInfo\n ? \"primary\"\n : currentInfo.localDisplayStatus === \"error\"\n ? \"danger\"\n : \"warning\"\n : undefined;\n\n const hasErrors = currentInfo?.localDisplayStatus === \"error\";\n const hasWarnings =\n currentInfo?.localDisplayStatus === \"warning\" ||\n (currentInfo?.localDisplayStatus === \"error\" &&\n currentInfo.issues.some((issue) => issue.severity === \"warning\"));\n\n const formManager = useFormManager();\n const schema = useMemo(\n () => currentInfo && formManager.schema(currentInfo.path),\n [currentInfo, formManager],\n );\n\n // Whether the active issues panel path has been registered at all\n const isRegistered = useIsRegistered(currentPagePath);\n const lastRegisteredPath = useRef<AbsolutePath | null>(null);\n if (isRegistered) {\n lastRegisteredPath.current = currentPagePath;\n }\n const hasBeenRegistered =\n isRegistered || lastRegisteredPath?.current?.equals(currentPagePath);\n\n // Sticky style for card header\n const [cardEl, setCardEl] = useState<HTMLDivElement | null>(null);\n const headerRef = useRef<HTMLDivElement | null>(null);\n useScrollPosition(\n cardEl,\n useCallback(\n (scrollPosition) =>\n setBoolDataAttr(\n headerRef.current,\n \"stuck\",\n (scrollPosition?.top ?? 0) > 0,\n ),\n [],\n ),\n );\n\n const renderIssuesList = (severity: ValidationIssueSeverity) =>\n (severity === \"error\" ? hasErrors : hasWarnings) && (\n <>\n <h3 className={prefix(\"issues-panel__issues-list-title\")}>\n {severity === \"error\" ? errorsLabel?.() : warningsLabel?.()}\n </h3>\n\n <ul className={prefix(\"issues-panel__issues-list\")}>\n {currentInfo!.issues\n .filter((issue) => issue.severity === severity)\n .map((issue, i) => (\n <li\n key={i}\n className={prefix(\"issues-panel__issue\")}\n data-severity={issue.severity}\n >\n <IssueMessage\n path={currentInfo!.path}\n issue={issue}\n schema={schema!}\n displayIssueCode={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n issueCodeProps={{\n className: prefix(\"issues-panel__issue-code\"),\n }}\n />\n </li>\n ))}\n </ul>\n </>\n );\n\n const combinedCardRef = useCombinedRef(setCardEl, forwardedRef);\n const combinedHeaderRef = useCombinedRef(headerRef, headerProps?.ref);\n return (\n <Card\n variant=\"subtle\"\n mergeSections\n className={cx(\n prefix(\"issues-panel\"),\n prefix(\"issues-panel--messages\"),\n className,\n )}\n {...otherProps}\n color={relevantColor ?? \"neutral\"}\n ref={combinedCardRef}\n >\n <CardHeader\n {...headerProps}\n className={cx(prefix(\"issues-panel__header\"), headerProps?.className)}\n ref={combinedHeaderRef}\n >\n {renderControls(relevantColor ?? \"primary\")}\n\n {/* Initialisation spinner. */}\n {!initialized && (\n <Spinner\n size=\"lg\"\n {...loadingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__loading-spinner\"),\n loadingSpinnerProps?.className,\n )}\n />\n )}\n\n {initialized && (\n <>\n {/* Panel icon. */}\n <Icon\n color={relevantColor}\n size=\"lg\"\n {...iconProps}\n className={cx(prefix(\"issues-panel__icon\"), iconProps?.className)}\n icon={relevantIcon!}\n />\n\n <CardTitle\n role=\"presentation\"\n aria-live=\"polite\"\n {...titleProps}\n className={cx(\n prefix(\"issues-panel__title\"),\n titleProps?.className,\n )}\n >\n {nPages === 0 ? (\n noIssuesMessage\n ) : hasBeenRegistered ? (\n currentPageExists ? (\n <Breadcrumb />\n ) : (\n resolvedTitle\n )\n ) : (\n <Spinner\n size=\"lg\"\n {...loadingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__loading-spinner\"),\n loadingSpinnerProps?.className,\n )}\n />\n )}\n </CardTitle>\n </>\n )}\n </CardHeader>\n\n <CardBody\n {...bodyProps}\n className={cx(prefix(\"issues-panel__body\"), bodyProps?.className)}\n >\n {currentInfo && hasBeenRegistered && renderIssuesList(\"error\")}\n {currentInfo && hasBeenRegistered && renderIssuesList(\"warning\")}\n {!currentInfo && nPages > 0 && (\n <div className={prefix(\"issues-panel__resolved-message\")}>\n {resolvedMessage}\n </div>\n )}\n </CardBody>\n </Card>\n );\n});\n\nfunction Breadcrumb() {\n const prefix = usePrefix();\n const breadcrumb = useActiveIssuesPanelBreadcrumb();\n\n return (\n breadcrumb &&\n (breadcrumb.length === 1 ? breadcrumb : breadcrumb.slice(1)).map(\n ({ path, label }) => (\n <CurrentPath key={path.toString()} path={path}>\n <span className={prefix(\"issues-panel__breadcrumb-item\")}>\n {label}\n </span>\n </CurrentPath>\n ),\n )\n );\n}\n","import {\n faCircleCheck,\n faCircleExclamation,\n faTriangleExclamation,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport type { IssuesTrackerResult } from \"@ostack.tech/kform-react\";\nimport {\n Card,\n CardHeader,\n CardTitle,\n cx,\n Icon,\n type IconButtonColor,\n Spinner,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport type { IssuesPanelProps } from \"./IssuesPanel.tsx\";\n\nexport interface IssuesPanelSummaryCardProps\n extends ComponentPropsWithoutRef<typeof Card>,\n Pick<\n IssuesPanelProps,\n | \"errorsLabel\"\n | \"warningsLabel\"\n | \"noIssuesMessage\"\n | \"headerProps\"\n | \"loadingSpinnerProps\"\n | \"titleProps\"\n | \"iconProps\"\n > {\n issuesTrackerResult: IssuesTrackerResult;\n renderControls: (buttonsColor?: IconButtonColor) => ReactNode;\n}\n\nexport const IssuesPanelSummaryCard = forwardRef<\n ComponentRef<typeof Card>,\n IssuesPanelSummaryCardProps\n>(function IssuesPanelSummaryCard(\n {\n issuesTrackerResult,\n errorsLabel,\n warningsLabel,\n noIssuesMessage,\n renderControls,\n headerProps,\n loadingSpinnerProps,\n titleProps,\n iconProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { initialized, info, errors, warnings } = issuesTrackerResult;\n const nPages = info?.length ?? 0;\n\n // Relevant icon and colour\n const relevantIcon = initialized\n ? errors > 0\n ? faCircleExclamation\n : warnings > 0\n ? faTriangleExclamation\n : faCircleCheck\n : undefined;\n const relevantColor = initialized\n ? errors > 0\n ? \"danger\"\n : warnings > 0\n ? \"warning\"\n : \"success\"\n : undefined;\n\n return (\n <Card\n variant=\"subtle\"\n mergeSections\n className={cx(\n prefix(\"issues-panel\"),\n prefix(\"issues-panel--summary\"),\n className,\n )}\n {...otherProps}\n color={initialized ? relevantColor : \"neutral\"}\n ref={forwardedRef}\n >\n <CardHeader\n {...headerProps}\n className={cx(prefix(\"issues-panel__header\"), headerProps?.className)}\n >\n {/* Initialisation spinner. */}\n {!initialized && (\n <Spinner\n size=\"lg\"\n {...loadingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__loading-spinner\"),\n loadingSpinnerProps?.className,\n )}\n />\n )}\n\n {initialized && (\n <>\n {/* Panel icon. */}\n <Icon\n color={relevantColor}\n size=\"lg\"\n {...iconProps}\n className={cx(prefix(\"issues-panel__icon\"), iconProps?.className)}\n icon={relevantIcon!}\n />\n\n <CardTitle\n role=\"presentation\"\n aria-live=\"polite\"\n {...titleProps}\n className={cx(\n prefix(\"issues-panel__title\"),\n titleProps?.className,\n )}\n >\n {nPages === 0 && noIssuesMessage}\n {nPages > 0 && (\n <>\n {errors > 0 && errorsLabel?.(errors)}\n {errors > 0 && warnings > 0 && \", \"}\n {warnings > 0 && warningsLabel?.(warnings)}\n </>\n )}\n </CardTitle>\n </>\n )}\n\n {renderControls(relevantColor)}\n </CardHeader>\n </Card>\n );\n});\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n compareSchemaPaths,\n type Schema,\n} from \"@ostack.tech/kform\";\nimport {\n type IssuesTrackerOptions,\n type LocatedValidationInfo,\n useController,\n useFormManager,\n useIssuesTracker,\n} from \"@ostack.tech/kform-react\";\nimport {\n type Card,\n type CardBody,\n type CardHeader,\n type CardTitle,\n type CloseButton,\n Container,\n cx,\n type Icon,\n type IconButton,\n type IconButtonColor,\n setBoolDataAttr,\n type Spinner,\n useCombinedRef,\n useControllableState,\n useIntersectionObserver,\n useLatestValues,\n useMeasure,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useDeferredValue,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useReportValidationFailures } from \"../../utils/useReportValidationFailures.ts\";\nimport {\n useFocus,\n useFormAppElement,\n useIssuesDisplayMode,\n useSetBottomPanelHeight,\n} from \"../FormApp\";\nimport {\n useIssuesPanelPath,\n useLatestInteraction,\n useSetStartIssuesNavigation,\n} from \"../FormApp/FormAppContext.ts\";\nimport { IssuesPanelControls } from \"./IssuesPanelControls.tsx\";\nimport { IssuesPanelMessagesCard } from \"./IssuesPanelMessagesCard.tsx\";\nimport { IssuesPanelSummaryCard } from \"./IssuesPanelSummaryCard.tsx\";\n\n/** Properties of the issues navigation component. */\nexport interface IssuesPanelProps\n extends Pick<IssuesTrackerOptions, \"issuesOrderCompareFn\">,\n Omit<\n ComponentPropsWithoutRef<typeof Card>,\n \"children\" | \"variant\" | \"color\"\n > {\n /** Default open state of the issues navigation panel. */\n defaultOpen?: boolean;\n /** Controlled open state of the issues navigation panel. */\n open?: boolean;\n /**\n * Function called whenever the open state of the issues navigation panel\n * changes.\n *\n * @param open New open state.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Whether to display issue codes together with each issue message.\n *\n * This property can also be set globally via the `displayIssueCodes` property\n * of the `FormApp`.\n */\n displayIssueCodes?: boolean;\n /**\n * Message to show for an error that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownErrorMessage?: ReactNode;\n /**\n * Message to show for a warning that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownWarningMessage?: ReactNode;\n /**\n * Errors label.\n *\n * @param errors Number of errors. If undefined, the function should return a\n * generic label with no number.\n */\n errorsLabel?: (errors?: number) => ReactNode;\n /**\n * Warnings label.\n *\n * @param warnings Number of warnings. If undefined, the function should\n * return a generic label with no number.\n */\n warningsLabel?: (warnings?: number) => ReactNode;\n /** Label of the focus button. */\n focusButtonLabel?: string;\n /** Label of the \"previous issue\" button. */\n previousIssueButtonLabel?: string;\n /** Label of the \"next issue\" button. */\n nextIssueButtonLabel?: string;\n /** Label of the \"first issue\" button. */\n firstIssueButtonLabel?: string;\n /** Label of the \"last issue\" button. */\n lastIssueButtonLabel?: string;\n /**\n * Text announced to assistive technologies with the current page out of the\n * total number of pages.\n *\n * @param currentPage Current page.\n * @param totalPages Total number of pages.\n */\n paginationLabel?: (currentPage: number, totalPages: number) => ReactNode;\n /** Message to display when there are no issues to report. */\n noIssuesMessage?: ReactNode;\n /** Title to display when all issues of the active path have been resolved. */\n resolvedTitle?: ReactNode;\n /** Message to display when all issues of the active path have been resolved. */\n resolvedMessage?: ReactNode;\n /** Properties to pass to the container element. */\n containerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the card header component. */\n headerProps?: ComponentPropsWithRef<typeof CardHeader>;\n /** Properties to pass to the card body component. */\n bodyProps?: ComponentPropsWithRef<typeof CardBody>;\n /** Properties to pass to the loading `Spinner` component. */\n loadingSpinnerProps?: ComponentPropsWithRef<typeof Spinner>;\n /** Properties to pass to the validating `Spinner` component. */\n validatingSpinnerProps?: ComponentPropsWithRef<typeof Spinner>;\n /** Properties to pass to the pagination element. */\n paginationProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the \"focus\" button component. */\n focusButtonProps?: Omit<ComponentPropsWithRef<typeof IconButton>, \"label\">;\n /** Properties to pass to the \"previous issue\" button component. */\n previousIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the \"next issue\" button component. */\n nextIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the \"first issue\" button component. */\n firstIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the \"last issue\" button component. */\n lastIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the icon component. */\n iconProps?: Omit<ComponentPropsWithRef<typeof Icon>, \"icon\">;\n /** Properties to pass to the title component. */\n titleProps?: ComponentPropsWithRef<typeof CardTitle>;\n /** Properties to pass to the close button component. */\n closeButtonProps?: ComponentPropsWithRef<typeof CloseButton>;\n}\n\n/** Component used to navigate through the issues of the form. */\nexport const IssuesPanel = forwardRef<\n ComponentRef<typeof Card>,\n IssuesPanelProps\n>(function ValidationPanel(\n {\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n displayIssueCodes,\n issuesOrderCompareFn,\n unknownErrorMessage,\n unknownWarningMessage,\n errorsLabel,\n warningsLabel,\n focusButtonLabel,\n previousIssueButtonLabel,\n nextIssueButtonLabel,\n firstIssueButtonLabel,\n lastIssueButtonLabel,\n paginationLabel,\n noIssuesMessage,\n resolvedTitle,\n resolvedMessage,\n containerProps,\n headerProps,\n bodyProps,\n loadingSpinnerProps,\n validatingSpinnerProps,\n paginationProps,\n focusButtonProps,\n previousIssueButtonProps,\n nextIssueButtonProps,\n firstIssueButtonProps,\n lastIssueButtonProps,\n titleProps,\n iconProps,\n closeButtonProps,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const printing = usePrinting();\n const [locale] = useLocale();\n errorsLabel ??= locale.IssuesPanel.errorsLabel;\n warningsLabel ??= locale.IssuesPanel.warningsLabel;\n focusButtonLabel ??= locale.IssuesPanel.focusButtonLabel;\n previousIssueButtonLabel ??= locale.IssuesPanel.previousIssueButtonLabel;\n nextIssueButtonLabel ??= locale.IssuesPanel.nextIssueButtonLabel;\n firstIssueButtonLabel ??= locale.IssuesPanel.firstIssueButtonLabel;\n lastIssueButtonLabel ??= locale.IssuesPanel.lastIssueButtonLabel;\n paginationLabel ??= locale.IssuesPanel.paginationLabel;\n noIssuesMessage ??= locale.IssuesPanel.noIssuesMessage;\n resolvedTitle ??= locale.IssuesPanel.resolvedTitle;\n resolvedMessage ??= locale.IssuesPanel.resolvedMessage;\n\n const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);\n const formIsLoading = useFormIsLoading();\n const issuesTrackerResult = useIssuesTracker(AbsolutePath.MATCH_ALL, {\n enabled: open && !formIsLoading && !printing,\n issuesOrderCompareFn,\n });\n useReportValidationFailures(issuesTrackerResult.info);\n const latestInteraction = useLatestInteraction();\n const deferredIssuesTrackerResult = useDeferredValue(issuesTrackerResult);\n const { info } = deferredIssuesTrackerResult;\n const nPages = info?.length ?? 0;\n\n const [currentPagePath, setCurrentPagePath] = useIssuesPanelPath();\n const currentPageController = useController(\n currentPagePath ?? AbsolutePath.ROOT,\n { enabled: open && !formIsLoading && currentPagePath !== null },\n );\n\n // Obtain the index of the current page from the page path, and keep track\n // of the last existing page that we've visited\n const lastExistingPageIndex = useRef<number | null>(null);\n const currentPageIndex = useMemo(() => {\n const idx = currentPagePath\n ? (info?.findIndex(({ path }) => currentPagePath.equals(path)) ?? -1)\n : -1;\n if (idx !== -1) {\n lastExistingPageIndex.current = idx;\n }\n return idx;\n }, [currentPagePath, info]);\n\n // Go to a specified page and focus its respective field\n const focus = useFocus();\n const goToPath = useCallback(\n (path: AbsolutePath | null) => {\n setCurrentPagePath(path);\n if (path) {\n focus(path);\n }\n },\n [focus, setCurrentPagePath],\n );\n const goToPage = useCallback(\n (page: number) => {\n if (nPages > 0) {\n const clampedPage = Math.max(0, Math.min(page, nPages - 1));\n const newCurrentPath = info![clampedPage].path ?? null;\n goToPath(newCurrentPath);\n }\n },\n [goToPath, info, nPages],\n );\n const goToPreviousPage = useCallback(() => {\n if (currentPageIndex !== -1) {\n goToPage(currentPageIndex - 1);\n } else {\n goToPage((lastExistingPageIndex.current ?? 1) - 1);\n }\n }, [currentPageIndex, goToPage]);\n const goToNextPage = useCallback(() => {\n if (currentPageIndex !== -1) {\n goToPage(currentPageIndex + 1);\n } else {\n goToPage(lastExistingPageIndex.current ?? 0);\n }\n }, [currentPageIndex, goToPage]);\n const goToFirstPage = useCallback(() => goToPage(0), [goToPage]);\n const goToLastPage = useCallback(\n () => goToPage(nPages - 1),\n [goToPage, nPages],\n );\n\n const formManager = useFormManager();\n const formSchema = useMemo(() => formManager.schema(), [formManager]);\n // Keep track of latest `issuesOrderCompareFn` to use when getting the most\n // relevant issue path\n const issuesOrderCompareFnRef = useRef(issuesOrderCompareFn);\n issuesOrderCompareFnRef.current = issuesOrderCompareFn;\n\n // Focus initial issue when starting\n const [starting, setStarting] = useState(false);\n useEffect(() => {\n if (issuesTrackerResult.initialized && starting) {\n if (issuesTrackerResult.info.length > 0) {\n goToPath(\n mostRelevantIssuePath(\n issuesTrackerResult.info,\n latestInteraction,\n formSchema,\n issuesOrderCompareFnRef.current,\n ),\n );\n }\n setStarting(false);\n }\n }, [\n formSchema,\n goToPath,\n issuesTrackerResult.info,\n issuesTrackerResult.initialized,\n latestInteraction,\n starting,\n ]);\n\n // Starts the issues navigation\n const listeners = useLatestValues({ onOpenChange });\n const start = useCallback(() => {\n if (!open) {\n setOpen(true);\n listeners.onOpenChange?.(true);\n }\n setCurrentPagePath(null);\n setStarting(true);\n lastExistingPageIndex.current = null;\n }, [listeners, open, setCurrentPagePath, setOpen]);\n\n // Expose the `start` function to the form app\n useSetStartIssuesNavigation(start);\n\n // Keep track of the container's height\n const [containerEl, setContainerEl] = useState<HTMLDivElement | null>(null);\n const setBottomPanelHeight = useSetBottomPanelHeight();\n useMeasure(\n containerEl,\n useCallback(\n (measurement) => setBottomPanelHeight(measurement?.height),\n [setBottomPanelHeight],\n ),\n );\n\n // Sticky style for panel\n const formAppEl = useFormAppElement();\n useIntersectionObserver(\n containerEl,\n useCallback(\n (e) => setBoolDataAttr(containerEl, \"stuck\", e.intersectionRatio === 1),\n [containerEl],\n ),\n useMemo(\n () => ({\n root: formAppEl,\n rootMargin: `0px 0px -1px 0px`,\n threshold: [1],\n }),\n [formAppEl],\n ),\n );\n\n // Hides the issues panel\n const close = useCallback(() => {\n if (open) {\n setOpen(false);\n listeners.onOpenChange?.(false);\n }\n }, [listeners, open, setOpen]);\n\n const renderControls = (buttonsColor?: IconButtonColor) => (\n <IssuesPanelControls\n nPages={nPages}\n currentPagePath={currentPagePath}\n currentPageIndex={currentPageIndex}\n currentPageController={currentPageController}\n goToPreviousPage={goToPreviousPage}\n goToNextPage={goToNextPage}\n goToFirstPage={goToFirstPage}\n goToLastPage={goToLastPage}\n buttonsColor={buttonsColor}\n closePanel={close}\n focusButtonLabel={focusButtonLabel}\n previousIssueButtonLabel={previousIssueButtonLabel}\n nextIssueButtonLabel={nextIssueButtonLabel}\n firstIssueButtonLabel={firstIssueButtonLabel}\n lastIssueButtonLabel={lastIssueButtonLabel}\n paginationLabel={paginationLabel}\n validatingSpinnerProps={validatingSpinnerProps}\n paginationProps={paginationProps}\n focusButtonProps={focusButtonProps}\n previousIssueButtonProps={previousIssueButtonProps}\n nextIssueButtonProps={nextIssueButtonProps}\n firstIssueButtonProps={firstIssueButtonProps}\n lastIssueButtonProps={lastIssueButtonProps}\n closeButtonProps={closeButtonProps}\n />\n );\n\n const displayMode = useIssuesDisplayMode();\n const combinedContainerRef = useCombinedRef(\n setContainerEl,\n containerProps?.ref,\n );\n return (\n open &&\n !printing && (\n <div\n {...containerProps}\n className={cx(\n prefix(\"issues-panel__container\"),\n containerProps?.className,\n )}\n ref={combinedContainerRef}\n >\n <Container asChild fluid=\"md\">\n {displayMode === \"inline\" ? (\n <IssuesPanelSummaryCard\n issuesTrackerResult={deferredIssuesTrackerResult}\n renderControls={renderControls}\n errorsLabel={errorsLabel}\n warningsLabel={warningsLabel}\n noIssuesMessage={noIssuesMessage}\n headerProps={headerProps}\n loadingSpinnerProps={loadingSpinnerProps}\n titleProps={titleProps}\n iconProps={iconProps}\n {...otherProps}\n ref={forwardedRef}\n />\n ) : (\n <IssuesPanelMessagesCard\n currentPagePath={currentPagePath}\n currentPageController={currentPageController}\n issuesTrackerResult={deferredIssuesTrackerResult}\n currentPageIndex={currentPageIndex}\n displayIssueCodes={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n renderControls={renderControls}\n errorsLabel={errorsLabel}\n warningsLabel={warningsLabel}\n noIssuesMessage={noIssuesMessage}\n resolvedTitle={resolvedTitle}\n resolvedMessage={resolvedMessage}\n headerProps={headerProps}\n bodyProps={bodyProps}\n loadingSpinnerProps={loadingSpinnerProps}\n titleProps={titleProps}\n iconProps={iconProps}\n {...otherProps}\n ref={forwardedRef}\n />\n )}\n </Container>\n </div>\n )\n );\n});\n\n/**\n * Function attempting to return the \"most relevant\" issue, given the list of\n * issue information, the path of the current page, and the path the user last\n * interacted with.\n */\nfunction mostRelevantIssuePath(\n info: LocatedValidationInfo[],\n latestInteraction: AbsolutePath,\n formSchema: Schema,\n issuesOrderCompareFn: IssuesTrackerOptions[\"issuesOrderCompareFn\"],\n): AbsolutePath {\n // Try to match the latest interaction exactly when a custom\n // `issuesOrderCompareFn` is provided, since we have no guarantee that the\n // first issue >= latest interaction will be the latest interaction itself\n // when it has an issue\n if (issuesOrderCompareFn) {\n for (const infoIssues of info) {\n if (latestInteraction.equals(infoIssues.path)) {\n return latestInteraction;\n }\n }\n }\n\n // Find index of first issues path >= latest interaction; if no such path\n // exists, set this index to the size of the info\n let indexOfInfoPathGteActivePath = info.findIndex(\n (issuesInfo) =>\n (issuesOrderCompareFn?.(issuesInfo.path, latestInteraction) ||\n compareSchemaPaths(formSchema, issuesInfo.path, latestInteraction)) >=\n 0,\n );\n if (indexOfInfoPathGteActivePath === -1) {\n indexOfInfoPathGteActivePath = info.length;\n }\n\n // Match a descendant of the latest interaction, or a descendant of one of its\n // ancestors\n let curPath = latestInteraction;\n while (!curPath.isRoot) {\n const curPathWithDescendants = curPath.append(\n AbsolutePathFragment.RecursiveWildcard,\n );\n for (let i = indexOfInfoPathGteActivePath; i < info.length; ++i) {\n if (curPathWithDescendants.matches(info[i].path)) {\n return info[i].path;\n }\n }\n for (let i = indexOfInfoPathGteActivePath - 1; i >= 0; --i) {\n if (curPathWithDescendants.matches(info[i].path)) {\n return info[i].path;\n }\n }\n curPath = curPath.parent();\n }\n return info[0].path;\n}\n","import { faFolderOpen } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n type ButtonProps,\n combineEventHandlers,\n useKeyboardShortcut,\n} from \"@ostack.tech/ui\";\nimport type { ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport {\n type FormLoaderOptions,\n useFormIsLoading,\n useFormLoader,\n} from \"../../utils/useFormLoader.tsx\";\nimport { useFormAppElement, useFormIsDisabled } from \"../FormApp\";\n\n/** Properties of the load action. */\nexport interface LoadActionProps<T = unknown>\n extends Omit<ButtonProps, \"children\">,\n FormLoaderOptions<T> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n}\n\n/** Action used to load a form from a file. */\nexport function LoadAction<T = unknown>({\n label,\n keybinds,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n ...otherProps\n}: LoadActionProps<T>) {\n const [locale] = useLocale();\n label ??= locale.LoadAction.label;\n keybinds ??= locale.LoadAction.keybinds;\n\n const { load } = useFormLoader({\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n });\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading;\n\n // Set-up keyboard shortcut\n const formAppEl = useFormAppElement();\n useKeyboardShortcut(keybinds, () => load(), {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <Button\n vertical\n variant=\"subtle\"\n icon={faFolderOpen}\n {...otherProps}\n onClick={combineEventHandlers(() => load(), onClick as never)}\n disabled={shouldDisable}\n loading={loading || formIsLoading}\n enabledWhenLoading={enabledWhenLoading}\n >\n {label}\n </Button>\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n formatNumericAsString,\n type Numeric,\n type NumericInputController,\n type NumericInputOptions,\n useNumericInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n NumericInput,\n type NumericValueRepresentations,\n useCombinedRef,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Kotlin integer types. */\nconst INTEGER_TYPES = [\"Byte\", \"Char\", \"Short\", \"Int\", \"Long\", \"BigInteger\"];\n\n/** Properties of the numeric control component. */\nexport interface NumericControlProps<T extends Numeric | null = Numeric | null>\n extends Omit<\n NumericInputOptions<T, string, ComponentRef<typeof NumericInput>>,\n \"enabled\" | \"formatFromString\" | \"parseToString\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof NumericInput>,\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"valueIsUnformattedString\"\n | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | NumericInputController<T, string, ComponentRef<typeof NumericInput>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Numeric control component supporting (possibly nullable) numeric schemas. */\nexport const NumericControl = forwardRef(function NumericControl<\n T extends Numeric | null = Numeric | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n valueIsInteger,\n scale,\n required,\n min,\n max,\n exclusiveMin,\n exclusiveMax,\n loading,\n disabled,\n readOnly,\n endAdornment,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: NumericControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof NumericInput>>,\n) {\n const [stringValue, setStringValue] = useState(\"\");\n const controller = useNumericInput<\n T,\n string,\n ComponentRef<typeof NumericInput>\n >(path, {\n enabled: !useFormIsLoading(),\n setFormattedValue: setStringValue,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLInputElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const latestStringValueRef = useRef(stringValue);\n latestStringValueRef.current = stringValue;\n const handleValueChange = useCallback(\n ({ stringValue }: NumericValueRepresentations) => {\n if (stringValue !== latestStringValueRef.current) {\n inputProps.onChange(stringValue);\n setStringValue(stringValue);\n }\n },\n [inputProps],\n );\n\n const schemaIsInteger = INTEGER_TYPES.includes(schema.typeInfo.name);\n if (schemaIsInteger && valueIsInteger !== undefined) {\n warnOnce(\n `NumericControl: At '${absolutePath.toString()}': Property ` +\n \"`valueIsInteger` has no effect (it will always be `true`) when the \" +\n \"control's schema is one of the integer types.\",\n );\n }\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedNumericInputRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <NumericInput\n value={stringValue}\n valueIsUnformattedString\n valueIsInteger={schemaIsInteger || valueIsInteger}\n scale={\n schemaIsInteger\n ? (scale ?? 0)\n : (scale ??\n (restrictions.scale == null\n ? undefined\n : (restrictions.scale as number)))\n }\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n min={\n min ??\n (restrictions.min == null\n ? undefined\n : formatNumericAsString(restrictions.min as T, schema))\n }\n max={\n max ??\n (restrictions.max == null\n ? undefined\n : formatNumericAsString(restrictions.max as T, schema))\n }\n exclusiveMin={\n exclusiveMin ??\n (restrictions.exclusiveMin == null\n ? undefined\n : formatNumericAsString(restrictions.exclusiveMin as T, schema))\n }\n exclusiveMax={\n exclusiveMax ??\n (restrictions.exclusiveMax == null\n ? undefined\n : formatNumericAsString(restrictions.exclusiveMax as T, schema))\n }\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={handleValueChange}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedNumericInputRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import type { AbsolutePath, Path } from \"@ostack.tech/kform\";\nimport { useResolvedPath } from \"@ostack.tech/kform-react\";\nimport { combineEventHandlers, Link } from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithoutRef, MouseEvent } from \"react\";\n\nimport { useFocus } from \"../FormApp\";\n\n/** Default function used to build a link's `href` from a path. */\nconst DEFAULT_HREF_BUILDER = (path: AbsolutePath) => path.toString();\n\n/** Properties of the path link component. */\nexport interface PathLinkProps\n extends Omit<ComponentPropsWithoutRef<typeof Link>, \"href\"> {\n /** KForm path to link to. */\n to: string | Path;\n /**\n * Function used to build the link's `href` from the path.\n *\n * @default (path) => path.toString()\n */\n buildHref?: (path: AbsolutePath) => string;\n}\n\n/** Link to a KForm path. */\nexport function PathLink({\n to,\n buildHref = DEFAULT_HREF_BUILDER,\n onClick,\n ...otherProps\n}: PathLinkProps) {\n const focus = useFocus();\n const path = useResolvedPath(to);\n\n const handleClick = (evt: MouseEvent) => {\n evt.preventDefault();\n focus(path);\n };\n\n return (\n <Link\n href={buildHref(path)}\n {...otherProps}\n onClick={combineEventHandlers(onClick, handleClick, {\n checkDefaultPrevented: true,\n })}\n />\n );\n}\n","import { faPrint } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n type ButtonProps,\n combineEventHandlers,\n PrinterTrigger,\n useKeyboardShortcut,\n usePrint,\n usePrinterDocumentTitle,\n usePrintInProgress,\n} from \"@ostack.tech/ui\";\nimport { format } from \"date-fns\";\nimport type { MouseEvent, ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useFormAppElement, useFormIsDisabled, useFormTitle } from \"../FormApp\";\n\n/** Properties of the print action. */\nexport interface PrintActionProps extends Omit<ButtonProps, \"children\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n}\n\n/**\n * Action used to print the form application. Requires the `<FormApp>` component\n * to be wrapped in a `<Printer>` component, and for the `<PrinterContent>` to\n * wrap all annexes/pages/form controls.\n *\n * This typically looks something like:\n *\n * ```tsx\n * <Printer>\n * <FormApp>\n * <PrinterContent>\n * <TopBar>\n * …\n * <PrintAction />…\n * </TopBar>\n * …\n * </PrinterContent>\n * </FormApp>\n * </Printer>;\n * ```\n */\nexport function PrintAction({\n label,\n keybinds,\n disabled,\n loading,\n enabledWhenLoading,\n onClick,\n ...otherProps\n}: PrintActionProps) {\n const [locale] = useLocale();\n label ??= locale.PrintAction.label;\n keybinds ??= locale.PrintAction.keybinds;\n\n const printInProgress = usePrintInProgress();\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading ||\n printInProgress;\n\n // Set-up keyboard shortcut\n const formAppEl = useFormAppElement();\n const formTitle = useFormTitle();\n const print = usePrint();\n\n // Only provide a default `documentTitle` if the one is not provided in the\n // `Printer` component\n const printerHasDocumentTitle = !!usePrinterDocumentTitle();\n const handlePrint = (evt: MouseEvent | KeyboardEvent) => {\n evt.preventDefault();\n void print(\n printerHasDocumentTitle\n ? undefined\n : { documentTitle: defaultDocumentTitle(formTitle) },\n );\n };\n\n useKeyboardShortcut(keybinds, handlePrint, {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <PrinterTrigger\n onClick={combineEventHandlers(onClick, handlePrint, {\n checkDefaultPrevented: true,\n })}\n >\n <Button\n vertical\n variant=\"subtle\"\n icon={faPrint}\n {...otherProps}\n loading={loading || printInProgress}\n disabled={shouldDisable}\n >\n {label}\n </Button>\n </PrinterTrigger>\n );\n}\n\n/** Default document title when one is not provided. */\nfunction defaultDocumentTitle(formTitle?: string) {\n const date = format(new Date(), \"yyyy-MM-dd\");\n return [formTitle, date].filter(Boolean).join(\" \");\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n equals,\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n Radio,\n RadioGroup,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type Key,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport {\n formatSelectionValueAsOptionIndex,\n parseSelectionValueFromOptionIndex,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Radio in object notation. */\nexport type RadioObject<T = unknown> = Omit<\n ComponentPropsWithRef<typeof Radio>,\n \"value\" | \"children\"\n> & {\n /** Option value. */\n value: T;\n /** Option's rendered text. */\n text?: ReactNode;\n /** Option's unique key. */\n key?: Key;\n};\n\n/** Properties of the radio group control component. */\nexport interface RadioGroupControlProps<T = unknown>\n extends Omit<\n InputOptions<T, string, ComponentRef<typeof RadioGroup>>,\n \"enabled\" | \"format\" | \"parse\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof RadioGroup>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"children\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /** RadioGroup control options. */\n options: RadioObject<T>[];\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n InputController<T, string, ComponentRef<typeof RadioGroup>> | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Radio group control component supporting schemas of any type. */\nexport const RadioGroupControl = forwardRef(function RadioGroupControl<\n T = unknown,\n>(\n {\n path,\n options,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n showClearButton = false,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: RadioGroupControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof RadioGroup>>,\n) {\n const [value, setValue] = useState<T>();\n const formattedValue = useMemo(\n () => formatSelectionValueAsOptionIndex(value, options),\n [options, value],\n );\n const controller = useInput<T, string, ComponentRef<typeof RadioGroup>>(\n path,\n {\n enabled: !useFormIsLoading(),\n parse: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n format: useCallback(\n (value: T | undefined) =>\n formatSelectionValueAsOptionIndex(value, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n setValue(\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n },\n );\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { nullable, restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLDivElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string) =>\n setValue(\n parseSelectionValueFromOptionIndex(formattedValue, schema, options),\n ),\n [options, schema],\n );\n\n // Get representation of the value that the control will be cleared to. When\n // `showClearButton` is \"auto\", we hide the button if the current value is\n // the same as the \"cleared value\".\n const clearedValue = nullable ? null : schema.initialValue;\n const clearedIdx = useMemo(\n () => options.findIndex((option) => equals(option.value, clearedValue)),\n [clearedValue, options],\n );\n const clearedFormattedValue = clearedIdx === -1 ? \"\" : clearedIdx.toString();\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedRadioGroupRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <RadioGroup\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n showClearButton={\n showClearButton === \"auto\"\n ? formattedValue !== clearedFormattedValue\n : showClearButton\n }\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedRadioGroupRef}\n >\n {options.map(({ value, text, key, ...radioProps }, i) => (\n <Radio key={key ?? i} value={i} {...radioProps}>\n {text ?? value?.toString() ?? \"\"}\n </Radio>\n ))}\n </RadioGroup>\n {inlineIssues}\n {popoverIssues}\n </>\n );\n});\n","import { AbsolutePath } from \"@ostack.tech/kform\";\nimport { useFormController, useFormManager } from \"@ostack.tech/kform-react\";\nimport { useToastManager } from \"@ostack.tech/ui\";\nimport {\n fileSave,\n type FileSystemHandle,\n supported,\n type WellKnownDirectory,\n} from \"browser-fs-access\";\nimport { format } from \"date-fns\";\nimport { type ReactNode, useMemo } from \"react\";\n\nimport { useFormTitle } from \"../components/FormApp\";\nimport { useLocale } from \"../providers/LocalizationProvider\";\n\n/**\n * Options that can be passed to the {@link useFormSaver} hook, or to its\n * resulting `save`/`saveAs` functions.\n */\nexport interface FormSaverOptions<T = unknown> {\n /**\n * When set, if modern file system APIs are available and the form has been\n * previously loaded or saved, then the file will be written over the\n * previously saved/loaded file.\n *\n * @default false\n */\n overwrite?: boolean;\n /**\n * Function used to encode the form, given its value.\n *\n * Note that when returning a string, the string is converted into a `Blob`\n * using the first provided mime type in `mimeTypes` as its type, _i.e._ it is\n * converted as `new Blob([encodedValue], { type: mimeTypes?.[0] })`.\n *\n * @param formValue Value of the form.\n * @returns Encoded form value as a string, blob, response, or a promise to\n * either type.\n */\n encode?: (\n formValue: T,\n ) => string | Blob | Response | PromiseLike<string | Blob | Response>;\n /**\n * Path of the value being saved.\n *\n * @default AbsolutePath.ROOT\n */\n path?: string | AbsolutePath;\n /**\n * Suggested file name.\n *\n * A function may be provided which will be called with the form value right\n * before invoking the save.\n */\n fileName?: string | ((formValue: T) => string | PromiseLike<string>);\n /**\n * Acceptable file extensions. Extensions should include the leading dot.\n *\n * _E.g._ `[\".json\", \".txt\"]`\n *\n * @default [\"\"]\n */\n extensions?: string[];\n /**\n * Acceptable MIME types.\n *\n * _E.g._ `[\"application/json\", \"text/plain\"]`\n *\n * @default [ ]\n */\n mimeTypes?: string[];\n /**\n * Suggested file description.\n *\n * @default \"\"\n */\n description?: string;\n /** Directory to present when starting to save. */\n startIn?: WellKnownDirectory | FileSystemHandle;\n /** Excludes the \"accept all\" option. */\n excludeAcceptAllOption?: boolean;\n /**\n * By specifying an ID, the user agent can remember different directories for\n * different IDs.\n */\n id?: string;\n /**\n * Whether to set the form as pristine when saving.\n *\n * @default true\n */\n setPristineOnSave?: boolean;\n /**\n * Message to show in a toast when successfully saving the form to a file. Can\n * be set to `null` to not show any message.\n *\n * @param fileHandle Handle to the saved file.\n * @returns Message to show in a toast.\n */\n successMessage?:\n | ReactNode\n | ((fileHandle: FileSystemFileHandle) => ReactNode);\n /**\n * Message to show in a toast when an error occurs while saving the form to a\n * file. Can be set to `null` to not show any message.\n *\n * @param fileHandle Handle of the file over which the save was attempted, or\n * `null` if no such file exists.\n * @param error Error that occurred.\n * @returns Message to show in a toast.\n */\n errorMessage?:\n | ReactNode\n | ((fileHandle: FileSystemFileHandle | null, error: unknown) => ReactNode);\n}\n\n/** Result of the {@link useFormSaver} hook. */\nexport interface FormSaverResult<T> {\n /**\n * Function used to save the form.\n *\n * @param options Options used for saving the form.\n * @returns Promise which resolves once the form has been saved.\n */\n save: (options?: FormSaverOptions<T>) => Promise<void>;\n /** Whether the browser supports modern file system APIs used for saving. */\n supportsFileSystemAPIs: boolean;\n}\n\n/** Hook exposing functions used to save the form to a file. */\nexport function useFormSaver<T = unknown>({\n overwrite,\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n setPristineOnSave,\n successMessage,\n errorMessage,\n}: FormSaverOptions<T> = {}): FormSaverResult<T> {\n const [locale] = useLocale();\n const formManager = useFormManager();\n const { getState, _setState } = useFormController();\n const { addToast } = useToastManager();\n const formTitle = useFormTitle();\n\n return useMemo(() => {\n async function save<T = unknown>({\n overwrite,\n path = AbsolutePath.ROOT,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id = \"\",\n setPristineOnSave = true,\n successMessage,\n errorMessage,\n }: FormSaverOptions<T>) {\n if (!encode) {\n throw new Error(\"No `encode` function was provided.\");\n }\n if (successMessage === undefined) {\n successMessage = locale.SaveAction.successMessage;\n }\n if (errorMessage === undefined) {\n errorMessage = locale.SaveAction.errorMessage;\n }\n\n _setState({ saving: true } as any);\n let fileHandle: FileSystemFileHandle | null =\n (getState() as any).latestFileHandles?.[id] ?? null;\n try {\n const [encodedForm, suggestedFileName] = await formManager.get<\n T,\n [string | Blob | Response, string | undefined]\n >(path, (value) =>\n Promise.all([\n encode(value),\n fileHandle\n ? fileHandle.name\n : typeof fileName === \"function\"\n ? fileName(value)\n : fileName,\n ]),\n );\n\n fileHandle = await fileSave(\n typeof encodedForm === \"string\"\n ? new Blob([encodedForm], { type: mimeTypes?.[0] })\n : encodedForm,\n {\n fileName:\n suggestedFileName || defaultFileName(formTitle, extensions?.[0]),\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n },\n overwrite ? fileHandle : null,\n );\n\n if (setPristineOnSave) {\n await formManager.setPristine(path);\n }\n\n _setState(\n (state: any) =>\n ({\n latestFileHandles: {\n ...state.latestFileHandles,\n [id]: fileHandle,\n },\n }) as any,\n );\n\n // When modern file system APIs aren't available, the browser will show\n // a notification for the downloaded file so the toast is unnecessary\n if (supported) {\n const message =\n typeof successMessage == \"function\"\n ? successMessage(fileHandle!)\n : successMessage;\n if (message != null) {\n addToast(message, { severity: \"success\" });\n }\n }\n } catch (err) {\n // User aborted\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(err);\n }\n const message =\n typeof errorMessage == \"function\"\n ? errorMessage(fileHandle, err)\n : errorMessage;\n if (message != null) {\n addToast(message, { severity: \"danger\" });\n }\n } finally {\n _setState({ saving: false } as any);\n }\n }\n\n return {\n save: (options = {}) =>\n save({\n overwrite,\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n setPristineOnSave,\n successMessage,\n errorMessage,\n ...options,\n }),\n supportsFileSystemAPIs: supported,\n };\n }, [\n _setState,\n addToast,\n description,\n encode,\n errorMessage,\n excludeAcceptAllOption,\n extensions,\n fileName,\n formManager,\n formTitle,\n getState,\n id,\n locale.SaveAction.errorMessage,\n locale.SaveAction.successMessage,\n mimeTypes,\n overwrite,\n path,\n setPristineOnSave,\n startIn,\n successMessage,\n ]);\n}\n\n/** Hook exposing whether the form is currently being saved. */\nexport function useFormIsSaving() {\n return useFormController().useState((state) => (state as any).saving);\n}\n\n/** Default file name when one is not provided. */\nfunction defaultFileName(formTitle?: string, extension?: string) {\n const date = format(new Date(), \"yyyy-MM-dd\");\n return [[formTitle, date].filter(Boolean).join(\" \"), extension]\n .filter(Boolean)\n .join(\"\");\n}\n","import { faCaretDown, faFloppyDisk } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n ButtonGroup,\n type ButtonProps,\n combineEventHandlers,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n IconButton,\n useKeyboardShortcut,\n} from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport {\n type FormSaverOptions,\n useFormIsSaving,\n useFormSaver,\n} from \"../../utils/useFormSaver.tsx\";\nimport { useFormAppElement } from \"../FormApp\";\n\n/** Properties of the save action. */\nexport interface SaveActionProps<T = unknown>\n extends Omit<ButtonProps, \"children\">,\n Omit<FormSaverOptions<T>, \"overwrite\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n /**\n * Whether to disable the overwriting behaviour of the “save” button. When\n * set, the “save” button will function as the “save as” button and the “save\n * as” button will not be rendered.\n *\n * This property only affects browsers that support modern file system APIs,\n * since other browsers already function in the above-mentioned way.\n */\n disableOverwrite?: boolean;\n /** Label of the save options button. */\n saveOptionsLabel?: ReactNode;\n /** Label of the action's \"save as\" sub-action. */\n saveAsLabel?: ReactNode;\n /**\n * Keybinds for triggering the \"save as\" sub-action. Set to `null` to disable\n * the keyboard shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n saveAsKeybinds?: string | string[] | null;\n /** Properties to pass to the save options button component. */\n saveOptionsProps?: Omit<\n Partial<ComponentPropsWithRef<typeof IconButton>>,\n \"label\"\n >;\n /** Properties to pass to the save options dropdown menu component. */\n dropdownMenuProps?: ComponentPropsWithRef<typeof DropdownMenuContent>;\n}\n\n/** Action used to save the form to a file. */\nexport function SaveAction<T = unknown>({\n label,\n keybinds,\n disableOverwrite,\n saveOptionsLabel,\n saveAsLabel,\n saveAsKeybinds,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n variant = \"subtle\",\n color,\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n successMessage,\n errorMessage,\n saveOptionsProps,\n dropdownMenuProps,\n ...otherProps\n}: SaveActionProps<T>) {\n const [locale] = useLocale();\n label ??= locale.SaveAction.label;\n keybinds ??= locale.SaveAction.keybinds;\n saveOptionsLabel ??= locale.SaveAction.saveOptionsLabel;\n saveAsLabel ??= locale.SaveAction.saveAsLabel;\n saveAsKeybinds ??= locale.SaveAction.saveAsKeybinds;\n\n const { save, supportsFileSystemAPIs } = useFormSaver({\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n successMessage,\n errorMessage,\n });\n const formIsSaving = useFormIsSaving();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsSaving ||\n formIsLoading;\n\n // Set-up keyboard shortcuts\n const formAppEl = useFormAppElement();\n useKeyboardShortcut(keybinds, () => save({ overwrite: !disableOverwrite }), {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n useKeyboardShortcut(saveAsKeybinds, () => save(), {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n const saveButton = (\n <Button\n vertical\n variant={variant}\n color={color}\n icon={faFloppyDisk}\n {...otherProps}\n onClick={combineEventHandlers(\n () => save({ overwrite: !disableOverwrite }),\n onClick as never,\n )}\n disabled={shouldDisable}\n loading={loading || formIsSaving}\n enabledWhenLoading={enabledWhenLoading}\n >\n {label}\n </Button>\n );\n\n return supportsFileSystemAPIs && !disableOverwrite ? (\n <ButtonGroup>\n {saveButton}\n <DropdownMenu>\n <DropdownMenuTrigger>\n <IconButton\n variant={variant}\n color={color}\n icon={faCaretDown}\n {...saveOptionsProps}\n label={saveOptionsLabel}\n disabled={shouldDisable || saveOptionsProps?.disabled}\n style={{ minWidth: 20, ...saveOptionsProps?.style }}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" {...dropdownMenuProps}>\n <DropdownMenuItem onClick={() => save()} disabled={shouldDisable}>\n {saveAsLabel}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </ButtonGroup>\n ) : (\n saveButton\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n equals,\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport { combineEventHandlers, Select, useCombinedRef } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport type { OptionObject, OptionsGroupObject } from \"../../utils/options.ts\";\nimport {\n formatSelectionValueAsOptionIndex,\n optionObjectsToNodes,\n parseSelectionValueFromOptionIndex,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the select control component. */\nexport interface SelectControlProps<T = unknown>\n extends Omit<\n InputOptions<T, string, ComponentRef<typeof Select>>,\n \"enabled\" | \"format\" | \"parse\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Select>,\n | \"multiple\"\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"children\"\n | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /** Select control options. */\n options: (OptionsGroupObject<T> | OptionObject<T>)[];\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n InputController<T, string, ComponentRef<typeof Select>> | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Select control component supporting schemas of any type. */\nexport const SelectControl = forwardRef(function SelectControl<T = unknown>(\n {\n path,\n options: groupedOptions,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n showClearButton,\n endAdornment,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: SelectControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Select>>,\n) {\n const options = useMemo(\n () =>\n groupedOptions.reduce((options: OptionObject<T>[], optionOrGroup) => {\n if (\"options\" in optionOrGroup) {\n options.push(...optionOrGroup.options);\n } else {\n options.push(optionOrGroup);\n }\n return options;\n }, []),\n [groupedOptions],\n );\n const [value, setValue] = useState<T>();\n const formattedValue = useMemo(\n () => formatSelectionValueAsOptionIndex(value, options),\n [options, value],\n );\n const controller = useInput<T, string, ComponentRef<typeof Select>>(path, {\n enabled: !useFormIsLoading(),\n parse: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n format: useCallback(\n (value: T | undefined) =>\n formatSelectionValueAsOptionIndex(value, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n setValue(\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { getState, useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { nullable, restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLButtonElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string) =>\n setValue(\n parseSelectionValueFromOptionIndex(\n formattedValue,\n getState().schema,\n options,\n ),\n ),\n [getState, options],\n );\n\n // Get representation of the value that the control will be cleared to. When\n // `showClearButton` is \"auto\", we hide the button if the current value is\n // the same as the \"cleared value\".\n showClearButton ??= nullable ? \"auto\" : false;\n const clearedValue = nullable ? null : schema.initialValue;\n const clearedIdx = useMemo(\n () => options.findIndex((option) => equals(option.value, clearedValue)),\n [clearedValue, options],\n );\n const clearedFormattedValue = clearedIdx === -1 ? \"\" : clearedIdx.toString();\n\n const optionNodes = useMemo(\n () => optionObjectsToNodes(groupedOptions),\n [groupedOptions],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedSelectRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Select\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n showClearButton={\n showClearButton === \"auto\"\n ? formattedValue !== clearedFormattedValue\n : showClearButton\n }\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedSelectRef}\n >\n {optionNodes}\n </Select>\n {inlineIssues}\n </>\n );\n});\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Listable,\n type ListableInputController,\n type ListableInputOptions,\n useListableInput,\n} from \"@ostack.tech/kform-react\";\nimport { combineEventHandlers, Select, useCombinedRef } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport type { OptionObject, OptionsGroupObject } from \"../../utils/options.ts\";\nimport {\n formatSelectionValuesAsOptionIndices,\n optionObjectsToNodes,\n parseSelectionValuesFromOptionIndices,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the select multiple control component. */\nexport interface SelectMultipleControlProps<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n> extends Omit<\n ListableInputOptions<T, TListable, string[], ComponentRef<typeof Select>>,\n \"enabled\" | \"formatFromArray\" | \"parseToArray\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Select>,\n | \"multiple\"\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"children\"\n | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /** Select multiple control options. */\n options: (OptionsGroupObject<T> | OptionObject<T>)[];\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | ListableInputController<\n T,\n TListable,\n string[],\n ComponentRef<typeof Select>\n >\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Select multiple control component supporting (possibly nullable) listable\n * schemas with elements of any type.\n *\n * If the schema is nullable, this component sets the form value to `null` when\n * the control contains no elements. Note, however, that the form may still hold\n * an empty listable as value if set programmatically.\n */\nexport const SelectMultipleControl = forwardRef(function SelectMultipleControl<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n options: groupedOptions,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n endAdornment,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: SelectMultipleControlProps<T, TListable>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Select>>,\n) {\n const options = useMemo(\n () =>\n groupedOptions.reduce((options: OptionObject<T>[], optionOrGroup) => {\n if (\"options\" in optionOrGroup) {\n options.push(...optionOrGroup.options);\n } else {\n options.push(optionOrGroup);\n }\n return options;\n }, []),\n [groupedOptions],\n );\n const [arrayValue, setArrayValue] = useState<T[] | null>(null);\n const formattedValue = useMemo(\n () => formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options, arrayValue],\n );\n const controller = useListableInput<\n T,\n TListable,\n string[],\n ComponentRef<typeof Select>\n >(path, {\n enabled: !useFormIsLoading(),\n parseToArray: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n formatFromArray: useCallback(\n (arrayValue: T[] | null) =>\n formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { getState, useSchema, usePath, inputProps } = controller;\n const { restrictions } = useSchema().typeInfo;\n const absolutePath = usePath();\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<TListable, HTMLButtonElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string[]) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n getState().schema,\n options,\n ),\n ),\n [getState, options],\n );\n\n const optionNodes = useMemo(\n () => optionObjectsToNodes(groupedOptions),\n [groupedOptions],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedSelectRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Select\n multiple\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedSelectRef}\n >\n {optionNodes}\n </Select>\n {inlineIssues}\n </>\n );\n});\n","import { faArrowRight } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n type FormManager,\n type LocatedValidationWarning,\n PromiseCancellationException,\n type SealedLocatedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport {\n type SubmitOptions,\n useFormController,\n} from \"@ostack.tech/kform-react\";\nimport {\n Alert,\n AlertDialog,\n AlertDialogAction,\n AlertDialogBody,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n type ButtonProps,\n Checkbox,\n type CheckboxChecked,\n combineEventHandlers,\n cx,\n Stack,\n useKeyboardShortcut,\n useToastManager,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithRef,\n type MouseEvent,\n type ReactNode,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport {\n useFormAppElement,\n useFormIsDisabled,\n useStartIssuesNavigation,\n} from \"../FormApp\";\n\n/** Properties of the submit action. */\nexport interface SubmitActionProps<T = unknown, TSubmitResult = unknown>\n extends Omit<ButtonProps, \"children\" | \"onSubmit\">,\n Pick<Required<SubmitOptions<T, TSubmitResult>>, \"onSubmit\">,\n Omit<SubmitOptions<T, TSubmitResult>, \"onSubmit\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n /**\n * Whether users should confirm (by ticking a checkbox) that the submission\n * should proceed whenever the form contains warnings.\n *\n * @default true\n */\n confirmWarnings?: boolean;\n /** Title of the confirmation dialog which appears when submitting the form. */\n dialogTitle?:\n | ReactNode\n | ((formValue: T, warnings?: LocatedValidationWarning[]) => ReactNode);\n /**\n * Description of the confirmation dialog which appears when submitting the\n * form.\n */\n dialogDescription?:\n | ReactNode\n | ((formValue: T, warnings?: LocatedValidationWarning[]) => ReactNode);\n /**\n * Body of the confirmation dialog which appears when submitting the form.\n *\n * This property can be used to display a summary of the data being submitted\n * and will be displayed between the description and the “confirm warnings\n * alert”, when it exists.\n */\n dialogBody?:\n | ReactNode\n | ((formValue: T, warnings?: LocatedValidationWarning[]) => ReactNode);\n /**\n * Label of the checkbox which prompts users to confirm that they intend to\n * proceed with submission in the event of warnings in the form.\n */\n confirmWarningsCheckboxLabel?: ReactNode;\n /**\n * Text of the OK button in the confirmation dialog which appears when\n * submitting the form.\n */\n dialogOkText?: ReactNode;\n /**\n * Text of the cancel button in the confirmation dialog which appears when\n * submitting the form.\n */\n dialogCancelText?: ReactNode;\n /**\n * Message to show in a toast after a successful submission. Can be set to\n * `null` to not show any message.\n *\n * @param submitResult Result of `onSubmit`.\n * @returns Message to show in a toast.\n */\n successMessage?: ReactNode | ((submitResult: TSubmitResult) => ReactNode);\n /**\n * Message to show in a toast when an error occurs while submitting the form.\n * Can be set to `null` to not show any message.\n *\n * @param error Error that occurred.\n * @returns Message to show in a toast.\n */\n errorMessage?: ReactNode | ((error: unknown) => ReactNode);\n /** Properties to pass to the confirmation dialog content component. */\n dialogContentProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogContent>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog header component. */\n dialogHeaderProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogHeader>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog title component. */\n dialogTitleProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogTitle>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog body component. */\n dialogBodyProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogBody>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog description component. */\n dialogDescriptionProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogDescription>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog footer component. */\n dialogFooterProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogFooter>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog OK button component. */\n dialogOkButtonProps?: Omit<ComponentPropsWithRef<typeof Button>, \"children\">;\n /** Properties to pass to the confirmation dialog cancel button component. */\n dialogCancelButtonProps?: Omit<\n ComponentPropsWithRef<typeof Button>,\n \"children\"\n >;\n /** Properties to pass to the alert used to confirm warnings. */\n confirmWarningsAlertProps?: Omit<\n ComponentPropsWithRef<typeof Alert>,\n \"children\"\n >;\n /** Properties to pass to the checkbox used to confirm warnings. */\n confirmWarningsCheckboxProps?: Omit<\n ComponentPropsWithRef<typeof Checkbox>,\n \"checked\" | \"onCheckedChange\" | \"children\"\n >;\n}\n\n/**\n * Type of external issues accepted by the form manager's `addExternalIssues`\n * method.\n */\ntype ExternalValidationIssues = Parameters<FormManager[\"addExternalIssues\"]>[0];\n\n/** An object which is event-like. */\ntype EventLike = Pick<Event, \"preventDefault\" | \"defaultPrevented\">;\n\n/** Information about a submission. */\ninterface SubmissionInfo<T = unknown, TSubmitResult = unknown> {\n value: T;\n warnings?: LocatedValidationWarning[];\n resolve: (value: ExternalValidationIssues | TSubmitResult) => void;\n reject: (reason?: any) => void;\n}\n\n/** Action used to submit the form. */\nexport function SubmitAction<T = unknown, TSubmitResult = unknown>({\n onSubmit,\n onInvalidSubmit,\n onSuccessfulSubmit,\n onFailedSubmit,\n setTouchedOnSubmit,\n validateOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n label,\n keybinds,\n confirmWarnings = true,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n dialogTitle,\n dialogDescription,\n dialogBody,\n confirmWarningsCheckboxLabel,\n dialogOkText,\n dialogCancelText,\n successMessage,\n errorMessage,\n dialogContentProps,\n dialogHeaderProps,\n dialogTitleProps,\n dialogBodyProps,\n dialogDescriptionProps,\n dialogFooterProps,\n dialogOkButtonProps,\n dialogCancelButtonProps,\n confirmWarningsAlertProps,\n confirmWarningsCheckboxProps,\n ...otherProps\n}: SubmitActionProps<T, TSubmitResult>) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n label ??= locale.SubmitAction.label;\n keybinds ??= locale.SubmitAction.keybinds;\n dialogTitle ??= locale.SubmitAction.dialogTitle;\n dialogDescription ??= locale.SubmitAction.dialogDescription;\n dialogBody ??= locale.SubmitAction.dialogBody;\n confirmWarningsCheckboxLabel ??=\n locale.SubmitAction.confirmWarningsCheckboxLabel;\n dialogOkText ??= locale.SubmitAction.dialogOkText ?? label;\n dialogCancelText ??= locale.SubmitAction.dialogCancelText;\n if (successMessage === undefined) {\n successMessage = locale.SubmitAction.successMessage;\n }\n if (errorMessage === undefined) {\n errorMessage = locale.SubmitAction.errorMessage;\n }\n\n const [confirmingSubmission, setConfirmingSubmission] = useState(false);\n const startIssuesNavigation = useStartIssuesNavigation();\n const { addToast } = useToastManager();\n const { submit, useSubmitting } = useFormController<T>();\n const submitting = useSubmitting();\n const [runningOnSubmit, setRunningOnSubmit] = useState(false);\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const formAppEl = useFormAppElement();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading ||\n submitting;\n\n const [submissionInfo, setSubmissionInfo] = useState<SubmissionInfo<\n T,\n TSubmitResult\n > | null>(null);\n const [checkedWarnings, setCheckedWarnings] = useState<\n LocatedValidationWarning[]\n >([]);\n const allWarningsChecked =\n !submissionInfo?.warnings ||\n submissionInfo.warnings.every((warning) =>\n checkedWarnings.some((checkedWarning) => warning.equals(checkedWarning)),\n );\n\n const handleSubmit = (\n value: T,\n warnings?: LocatedValidationWarning[],\n event?: EventLike,\n ) => {\n event?.preventDefault?.();\n return new Promise<ExternalValidationIssues | TSubmitResult>(\n (resolve, reject) => {\n setConfirmingSubmission(true);\n setSubmissionInfo({ value, warnings, resolve, reject });\n },\n );\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open && !runningOnSubmit) {\n submissionInfo?.reject(\n new PromiseCancellationException(\"Submission cancelled\"),\n );\n setSubmissionInfo(null);\n setConfirmingSubmission(false);\n }\n };\n\n const handleInvalidSubmit = async (\n issues: SealedLocatedValidationIssue[],\n event?: EventLike,\n ) => {\n await startIssuesNavigation({ validate: false });\n onInvalidSubmit?.(issues, event);\n };\n\n const handleSuccessfulSubmit = (\n submitResult: TSubmitResult,\n event?: EventLike,\n ) => {\n const message =\n typeof successMessage === \"function\"\n ? successMessage(submitResult)\n : successMessage;\n if (message != null) {\n addToast(message, { severity: \"success\" });\n }\n onSuccessfulSubmit?.(submitResult, event);\n };\n\n const handleFailedSubmit = (error: unknown, event?: EventLike) => {\n if (error instanceof PromiseCancellationException) {\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(error);\n }\n const message =\n typeof errorMessage === \"function\" ? errorMessage(error) : errorMessage;\n if (message != null) {\n addToast(message, { severity: \"danger\" });\n }\n onFailedSubmit?.(error, event);\n };\n\n const handleConfirmSubmit = async (event: MouseEvent) => {\n event.preventDefault();\n if (!submissionInfo) {\n return;\n }\n\n const { value, warnings, resolve, reject } = submissionInfo;\n try {\n setRunningOnSubmit(true);\n resolve(await onSubmit(value, warnings, event));\n } catch (err) {\n reject(err);\n } finally {\n setRunningOnSubmit(false);\n handleOpenChange(false);\n }\n };\n\n const handleOnCheckedChange = (checked: CheckboxChecked) => {\n setCheckedWarnings(checked ? (submissionInfo?.warnings ?? []) : []);\n };\n\n const handleAction = (event: EventLike) =>\n submit(event, {\n onSubmit: handleSubmit,\n onInvalidSubmit: handleInvalidSubmit,\n onSuccessfulSubmit: handleSuccessfulSubmit,\n onFailedSubmit: handleFailedSubmit,\n setTouchedOnSubmit,\n validateOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n });\n\n // Set-up keyboard shortcut\n useKeyboardShortcut(keybinds, handleAction, {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <AlertDialog open={confirmingSubmission} onOpenChange={handleOpenChange}>\n <AlertDialogTrigger>\n <Button\n type=\"submit\"\n color=\"success\"\n icon={faArrowRight}\n iconPlacement=\"end\"\n {...otherProps}\n onClick={combineEventHandlers(handleAction, onClick as never)}\n disabled={shouldDisable}\n loading={loading || submitting}\n enabledWhenLoading={enabledWhenLoading}\n >\n {label}\n </Button>\n </AlertDialogTrigger>\n\n <AlertDialogContent\n color=\"primary\"\n {...dialogContentProps}\n portalProps={{\n container: formAppEl,\n ...dialogContentProps?.portalProps,\n }}\n >\n {submissionInfo && (\n <>\n <AlertDialogHeader {...dialogHeaderProps}>\n <AlertDialogTitle {...dialogTitleProps}>\n {typeof dialogTitle === \"function\"\n ? dialogTitle(submissionInfo.value, submissionInfo.warnings)\n : dialogTitle}\n </AlertDialogTitle>\n </AlertDialogHeader>\n\n <AlertDialogBody {...dialogBodyProps}>\n <Stack gap={3}>\n {dialogDescription && (\n <AlertDialogDescription\n {...dialogDescriptionProps}\n style={{ margin: 0, ...dialogDescriptionProps?.style }}\n className={cx(\n prefix(\"submit-action__dialog-description\"),\n dialogDescriptionProps?.className,\n )}\n >\n {typeof dialogDescription === \"function\"\n ? dialogDescription(\n submissionInfo.value,\n submissionInfo.warnings,\n )\n : dialogDescription}\n </AlertDialogDescription>\n )}\n\n {typeof dialogBody === \"function\"\n ? dialogBody(submissionInfo.value, submissionInfo.warnings)\n : dialogBody}\n\n {confirmWarnings &&\n (submissionInfo.warnings?.length ?? 0) > 0 && (\n <Alert\n severity=\"warning\"\n {...confirmWarningsAlertProps}\n className={cx(\n prefix(\"submit-action__confirm-warnings-alert\"),\n confirmWarningsAlertProps?.className,\n )}\n >\n <Checkbox\n status=\"warned\"\n {...confirmWarningsCheckboxProps}\n checked={allWarningsChecked}\n onCheckedChange={handleOnCheckedChange}\n >\n {confirmWarningsCheckboxLabel}\n </Checkbox>\n </Alert>\n )}\n </Stack>\n </AlertDialogBody>\n\n <AlertDialogFooter {...dialogFooterProps}>\n <AlertDialogCancel disabled={runningOnSubmit}>\n <Button variant=\"subtle\" {...dialogCancelButtonProps}>\n {dialogCancelText}\n </Button>\n </AlertDialogCancel>\n\n <AlertDialogAction onClick={handleConfirmSubmit}>\n <Button\n type=\"submit\"\n color=\"primary\"\n icon={faArrowRight}\n iconPlacement=\"end\"\n {...dialogOkButtonProps}\n loading={runningOnSubmit || dialogOkButtonProps?.loading}\n disabled={\n (confirmWarnings && !allWarningsChecked) ||\n dialogOkButtonProps?.disabled\n }\n >\n {dialogOkText}\n </Button>\n </AlertDialogAction>\n </AlertDialogFooter>\n </>\n )}\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import type { AbsolutePath, Table, TableRowId } from \"@ostack.tech/kform\";\nimport type { FormatterController } from \"@ostack.tech/kform-react\";\nimport { createContext, type Ref, useContext } from \"react\";\n\nimport type { UseRegisterControlResult } from \"../../utils/useRegisterControl.tsx\";\nimport type { TableControlRowController } from \"./TableControlColumn.tsx\";\n\n/** Value of the table control context. */\nexport interface TableControlContextValue<\n T = any,\n TTable extends Table<T> | null = Table<T> | null,\n> {\n controller: TableControlController<T, TTable>;\n autofocusRef: Ref<HTMLDivElement>;\n handleFocus: UseRegisterControlResult<HTMLDivElement>[\"handleFocus\"];\n size?: number;\n maxRows?: number;\n}\n\n/** Controller of the table control. */\nexport type TableControlController<\n T = any,\n TTable extends Table<T> | null = Table<T> | null,\n> = FormatterController<TTable, TableRowId[]> & {\n addRow: () => PromiseLike<void> | void;\n removeRow: (path: AbsolutePath) => PromiseLike<void> | void;\n};\n\n/** Table control context. */\nexport const TableControlContext =\n createContext<TableControlContextValue | null>(null);\n\n/** Hook providing access to the table control context. */\nexport function useTableControlContext<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>(): TableControlContextValue<T, TTable> {\n const tableControlContext = useContext(TableControlContext);\n if (!tableControlContext) {\n throw new Error(\"Table control context not in scope.\");\n }\n return tableControlContext as unknown as TableControlContextValue<T, TTable>;\n}\n\n/** Table control row context. */\nexport const TableControlRowContext =\n createContext<TableControlRowController | null>(null);\n\n/** Hook providing access to the table control row context. */\nexport function useTableControlRowContext<T>(): TableControlRowController<T> {\n const tableControlRowContext = useContext(TableControlRowContext);\n if (!tableControlRowContext) {\n throw new Error(\"Table control row context not in scope.\");\n }\n return tableControlRowContext as TableControlRowController<T>;\n}\n","import { DataTableCell, usePrinting } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useDeferredValue,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useTableControlRowContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control cell. */\nexport interface TableControlCellProps\n extends ComponentPropsWithoutRef<typeof DataTableCell> {}\n\n/** Cell of the table control. */\nexport const TableControlCell = forwardRef<\n ComponentRef<typeof DataTableCell>,\n TableControlCellProps\n>(function TableControlCell({ variant, ...otherProps }, forwardedRef) {\n const printing = usePrinting();\n const { useDisplayStatus } = useTableControlRowContext();\n const deferredDisplayStatus = useDeferredValue(useDisplayStatus());\n return (\n <DataTableCell\n variant={variant}\n // When the cell has a \"header\" variant, set its status from the row's\n // display status\n status={\n !printing && variant === \"header\"\n ? displayStatusToControlStatus(deferredDisplayStatus)\n : undefined\n }\n {...otherProps}\n ref={forwardedRef}\n />\n );\n});\n","import { CurrentPath, useController } from \"@ostack.tech/kform-react\";\nimport { DataTableRow, useStartPrintingTask } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n memo,\n useEffect,\n useMemo,\n} from \"react\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport { TableControlRowContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control row. */\nexport interface TableControlRowProps\n extends ComponentPropsWithoutRef<typeof DataTableRow> {}\n\n/** Row of a table control. */\nexport const TableControlRow = memo(\n forwardRef<ComponentRef<typeof DataTableRow>, TableControlRowProps>(\n function TableControlRow({ row, index, ...otherProps }, forwardedRef) {\n const controller = useController(row, {\n enabled: !useFormIsLoading() && row != null,\n });\n const path = controller.usePath();\n useRegisterController(controller);\n useRegisterLabel(path, row == null ? null : index + 1);\n\n // Start a printing task until the row is initialised\n const initialized = controller.useInitialized();\n const finishPrintingTask = useStartPrintingTask({ enabled: row != null });\n useEffect(() => {\n if (initialized) {\n finishPrintingTask();\n }\n }, [finishPrintingTask, initialized]);\n\n return (\n <CurrentPath path={path}>\n <TableControlRowContext.Provider\n value={useMemo(\n () => ({ index, ...controller }),\n [controller, index],\n )}\n >\n <DataTableRow\n row={row}\n index={index}\n {...otherProps}\n ref={forwardedRef}\n />\n </TableControlRowContext.Provider>\n </CurrentPath>\n );\n },\n ),\n);\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n arrayToTable,\n type CancellablePromise,\n indexOfTableRowId,\n isComputedSchema,\n type Path,\n sliceTable,\n type Table,\n type TableRowId,\n} from \"@ostack.tech/kform\";\nimport {\n type ControllerOptions,\n InvalidPathError,\n useFormatter,\n} from \"@ostack.tech/kform-react\";\nimport {\n cx,\n DataTable,\n type DataTableColumns,\n type DataTableContent,\n type DataTableScrollToOptions,\n useDataTableApiRef,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useImperativeHandle,\n useMemo,\n useState,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport { FormAppStatus, useOnPathFocus } from \"../FormApp\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\nimport type { TableControlApi } from \"./TableControlApi.ts\";\nimport { TableControlCell } from \"./TableControlCell.tsx\";\nimport type {\n TableControlColumn,\n TableControlColumns,\n TableControlStatus,\n} from \"./TableControlColumn.tsx\";\nimport {\n TableControlContext,\n useTableControlRowContext,\n} from \"./TableControlContext.ts\";\nimport { TableControlRow } from \"./TableControlRow.tsx\";\n\n/** Properties of the table control component. */\nexport interface TableControlProps<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n> extends Omit<\n ComponentPropsWithoutRef<typeof DataTable>,\n | \"columns\"\n | \"rows\"\n | \"getRows\"\n | \"rowKey\"\n | \"loading\"\n | \"defaultFilter\"\n | \"filter\"\n | \"onFilterChange\"\n | \"defaultSortBy\"\n | \"sortBy\"\n | \"defaultSortDirection\"\n | \"sortDirection\"\n | \"onSort\"\n | \"showSelectionColumn\"\n | \"defaultSelectedRows\"\n | \"selectedRows\"\n | \"onSelectedRowsChange\"\n | \"showAllRowsWhilePrinting\"\n | \"apiRef\"\n >,\n Omit<ControllerOptions<TTable>, \"enabled\"> {\n /** Control's path. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this table.\n *\n * This label has priority over the table's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /** Table control columns. */\n columns: TableControlColumns<T>;\n /**\n * Sets the maximum number of rows that the table can have. By default, if the\n * table's schema has a `MaxSize` validation, then its value is used.\n */\n maxRows?: number;\n /** Sets the table control as disabled. */\n disabled?: boolean;\n /** Sets the table control as read-only. */\n readOnly?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<TableControlApi<T, TTable> | undefined>;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Table control component supporting (possibly nullable) collection schemas. */\nexport const TableControl = forwardRef(function TableControl<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n columns,\n required,\n maxRows,\n disabled = false,\n readOnly = false,\n className,\n ...otherProps\n }: TableControlProps<T, TTable>,\n forwardedRef: ForwardedRef<ComponentRef<typeof DataTableContent>>,\n) {\n const prefix = usePrefix();\n const [ids, setIds] = useState<TableRowId[] | undefined>(undefined);\n const size = ids?.length;\n const dataTableApiRef = useDataTableApiRef();\n\n const controller = useFormatter<TTable, TableRowId[]>(path, {\n enabled: !useFormIsLoading(),\n format: useCallback(\n (value?: TTable) => (value ? sliceTable(value).map(([id]) => id) : []),\n [],\n ),\n setFormattedValue: setIds,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n\n const { useSchema, usePath, useInitialized, useExists } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const initialized = useInitialized();\n const exists = useExists();\n const { restrictions } = schema.typeInfo;\n const maxRowsRestriction =\n maxRows ??\n (typeof restrictions.maxSize === \"number\"\n ? restrictions.maxSize\n : undefined);\n const elementsSchema = controller.useState((state) =>\n state.formManager.schema(state.path.append(AbsolutePathFragment.Wildcard)),\n );\n\n if (schema.typeInfo.name !== \"Table\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected (possibly nullable) table schema, \" +\n \"but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n const ownController = useMemo(\n () => ({\n addRow: async () => {\n const { schema, initialized, exists, touched, dirty } =\n controller.getState();\n if (\n !initialized ||\n !exists ||\n (maxRowsRestriction != null && size! >= maxRowsRestriction)\n ) {\n return;\n }\n\n const initialRowValue = elementsSchema.initialValue;\n const setPromise: CancellablePromise<void> =\n schema.typeInfo.nullable && size === 0\n ? controller.set(arrayToTable([initialRowValue]) as TTable)\n : controller.set(\"-\", initialRowValue);\n setPromise.then(\n () =>\n void Promise.resolve().then(() =>\n dataTableApiRef.current!.goTo(size!),\n ),\n );\n\n if (!touched) {\n void controller.setTouched();\n }\n if (!dirty) {\n void controller.setDirty();\n }\n return setPromise;\n },\n removeRow: (path: AbsolutePath) => {\n const { formManager, schema, initialized, exists, touched, dirty } =\n controller.getState();\n if (!initialized || !exists) {\n return;\n }\n\n const removePromise =\n schema.typeInfo.nullable && size === 1\n ? controller.set(null as TTable)\n : formManager.remove(path);\n\n if (!touched) {\n void controller.setTouched();\n }\n if (!dirty) {\n void controller.setDirty();\n }\n return removePromise;\n },\n }),\n [\n maxRowsRestriction,\n controller,\n dataTableApiRef,\n elementsSchema.initialValue,\n size,\n ],\n );\n\n // Expose the control's API via `apiRef`\n const goToIndex = useCallback(\n (index: number, scrollOptions?: DataTableScrollToOptions) => {\n dataTableApiRef.current?.goTo(index, scrollOptions);\n },\n [dataTableApiRef],\n );\n const goToId = useCallback(\n (id: number, scrollOptions?: DataTableScrollToOptions) => {\n const { initialized, exists } = controller.getState();\n if (initialized && exists) {\n void controller.get((value) => {\n if (value) {\n const idx = indexOfTableRowId(value, id);\n if (idx !== -1) {\n dataTableApiRef.current?.goTo(idx, scrollOptions);\n }\n }\n });\n }\n },\n [controller, dataTableApiRef],\n );\n\n // Register the control\n const {\n displayDisabled,\n displayReadOnly,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<TTable, HTMLDivElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n });\n const controlIsDisabled = displayDisabled || disabled;\n const controlIsReadOnly =\n displayReadOnly || readOnly || isComputedSchema(schema);\n\n useImperativeHandle(\n apiRef,\n () => ({\n ...controller,\n goToIndex,\n goToId,\n }),\n [controller, goToId, goToIndex],\n );\n\n // Go to row with active path when it changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n if (\n exists &&\n focusedPath &&\n absolutePath.resolve(AbsolutePath.DESCENDANTS).contains(focusedPath)\n ) {\n const rowId = focusedPath.fragments[absolutePath.size];\n if (rowId instanceof AbsolutePathFragment.Id) {\n goToId(+rowId.id, { align: \"center\", behavior: \"smooth\" });\n }\n }\n },\n [absolutePath, exists, goToId],\n ),\n );\n\n const printing = usePrinting();\n const dataTableColumns: DataTableColumns<AbsolutePath> = useMemo(\n () =>\n tableControlToDataTableColumns(columns, {\n disabled: controlIsDisabled,\n readOnly: controlIsReadOnly,\n printing,\n }),\n [columns, controlIsDisabled, controlIsReadOnly, printing],\n );\n\n const tableControlController = useMemo(\n () => ({ ...controller, ...ownController }),\n [controller, ownController],\n );\n\n const [inlineIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n return (\n <FormAppStatus disabled={controlIsDisabled} readOnly={controlIsReadOnly}>\n <TableControlContext.Provider\n value={{\n controller: tableControlController as never,\n autofocusRef,\n handleFocus,\n size,\n maxRows: maxRowsRestriction,\n }}\n >\n <DataTable\n className={cx(prefix(\"table-control\"), className)}\n displayMode=\"scrolled\"\n columns={dataTableColumns}\n rows={ids}\n rowKey={(id: TableRowId) => id}\n required={required ?? restrictions.required === true}\n loading={!initialized}\n renderRow={(props) => <TableControlRow {...props} />}\n renderCell={(props) => <TableControlCell {...props} />}\n showAllRowsWhilePrinting\n apiRef={dataTableApiRef}\n {...otherProps}\n ref={forwardedRef}\n />\n {inlineIssues}\n </TableControlContext.Provider>\n </FormAppStatus>\n );\n});\n\nfunction tableControlToDataTableColumns<T>(\n columns: TableControlColumns<T>,\n tableControlStatus: TableControlStatus,\n columnNamePrefix = \"col\",\n): DataTableColumns<AbsolutePath> {\n return columns.reduce(\n (dataColumns: DataTableColumns<AbsolutePath>, dataColumnOrFn, i) => {\n const dataColumn =\n typeof dataColumnOrFn === \"function\"\n ? dataColumnOrFn(tableControlStatus)\n : dataColumnOrFn;\n if (dataColumn) {\n const { subColumns, render, ...otherColumn } = dataColumn;\n dataColumns[`${columnNamePrefix}-${i}`] = {\n ...otherColumn,\n subColumns:\n subColumns &&\n tableControlToDataTableColumns(\n subColumns,\n tableControlStatus,\n `${columnNamePrefix}-${i}`,\n ),\n filterable: false,\n render:\n render && (() => <TableControlCellRenderer render={render} />),\n };\n }\n return dataColumns;\n },\n {},\n );\n}\n\n/** Properties of the table control cell renderer. */\nexport interface TableControlCellRendererProps<T = unknown> {\n render: NonNullable<TableControlColumn<T>[\"render\"]>;\n}\n\n/** Renderer of a table control cell. */\nexport function TableControlCellRenderer<T = unknown>({\n render,\n}: TableControlCellRendererProps<T>) {\n const controller = useTableControlRowContext<T>();\n return render(controller);\n}\n","import { faPlus } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n combineEventHandlers,\n cx,\n Slot,\n usePrintClassNames,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsDisabled, useFormIsReadOnly } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport { useTableControlContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control add row trigger component. */\nexport interface TableControlAddRowTriggerProps\n extends ComponentPropsWithoutRef<typeof Button> {\n /**\n * Text displayed on the button rendered by default when no `children` are\n * provided. If `children` are provided, this property has no effect.\n */\n defaultButtonText?: ReactNode;\n /** Function called after the row has been added. */\n onRowAdded?: () => void;\n /**\n * Whether to show the trigger when the table is read-only.\n *\n * @default false\n */\n showWhenReadOnly?: boolean;\n /**\n * Whether to show the trigger when it is being printed.\n *\n * @default false\n */\n showWhilePrinting?: boolean;\n}\n\n/**\n * Trigger used to add a new row to a table control.\n *\n * By default, it renders a button with text `defaultButtonText`, however, this\n * can be overriden by providing `children`.\n */\nexport const TableControlAddRowTrigger = forwardRef<\n ComponentRef<typeof Button>,\n TableControlAddRowTriggerProps\n>(function TableControlAddRowTrigger(\n {\n defaultButtonText,\n onRowAdded,\n showWhenReadOnly,\n showWhilePrinting,\n disabled,\n onClick,\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n defaultButtonText ??= locale.TableControlAddRowTrigger.defaultButtonText;\n\n const { printHidden } = usePrintClassNames();\n const { controller, size, maxRows } = useTableControlContext();\n const controlIsDisabled = useFormIsDisabled();\n const controlIsReadOnly = useFormIsReadOnly();\n const setLatestInteraction = useSetLatestInteraction();\n\n const handleClick = async () => {\n await controller.addRow();\n setLatestInteraction(controller.getState().path);\n onRowAdded?.();\n };\n\n const shouldDisable = controller.useState(\n ({ initialized, exists }) =>\n !initialized ||\n !exists ||\n controlIsDisabled ||\n disabled ||\n controlIsReadOnly ||\n (maxRows != null && size! >= maxRows),\n );\n\n const As: any = Slot;\n return (\n (showWhenReadOnly || !controlIsReadOnly) && (\n <As\n className={cx(\n prefix(\"table-control__add-row-trigger\"),\n showWhilePrinting || printHidden,\n className,\n )}\n disabled={shouldDisable}\n onClick={combineEventHandlers(onClick, handleClick, {\n checkDefaultPrevented: true,\n })}\n {...otherProps}\n ref={forwardedRef}\n >\n {children ?? (\n <Button icon={faPlus} color=\"primary\">\n {defaultButtonText}\n </Button>\n )}\n </As>\n )\n );\n});\n","import type { Table, TableRowId } from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport type { DataTableScrollToOptions } from \"@ostack.tech/ui\";\nimport { type RefObject, useRef } from \"react\";\n\n/** Imperative table control API. */\nexport type TableControlApi<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n> = Controller<TTable> & {\n /**\n * Navigates to the row with the provided index.\n *\n * @param index Index of row to navigate to.\n * @param scrollOptions Options used to configure to scrolling to the row\n * (only relevant in scrolled display mode).\n */\n goToIndex: (index: number, scrollOptions?: DataTableScrollToOptions) => void;\n /**\n * Navigates to the row with the provided id.\n *\n * @param id Id of row to navigate to.\n * @param scrollOptions Options used to configure to scrolling to the row\n * (only relevant in scrolled display mode).\n */\n goToId: (id: TableRowId, scrollOptions?: DataTableScrollToOptions) => void;\n};\n\n/** Hook used to access the table control API. */\nexport function useTableControlApiRef<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>(): RefObject<TableControlApi<T, TTable> | null> {\n return useRef<TableControlApi<T, TTable>>(null);\n}\n","import { faTrash } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n combineEventHandlers,\n IconButton,\n Slot,\n useAlertDialog,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsDisabled, useFormIsReadOnly } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport {\n useTableControlContext,\n useTableControlRowContext,\n} from \"./TableControlContext.ts\";\n\n/** Properties of the table control remove row trigger component. */\nexport interface TableControlRemoveRowTriggerProps\n extends Omit<\n Partial<ComponentPropsWithoutRef<typeof IconButton>>,\n \"children\"\n > {\n /**\n * Whether to show a confirmation message when removing a row.\n *\n * @default false\n */\n showConfirmation?: boolean;\n /**\n * Function called after confirmation that the row is to be removed (this\n * function is called even if `showConfirmation` is not set).\n */\n onConfirmRowRemoval?: () => void;\n /** Function called after the row has been removed. */\n onRowRemoved?: () => void;\n /**\n * Label displayed on the icon button rendered by default when no `children`\n * are provided. If `children` are provided, this property has no effect.\n */\n defaultButtonLabel?: ReactNode;\n /** Title of the confirmation dialog when `showConfirmation` is `true`. */\n confirmDialogTitle?: ReactNode;\n /**\n * Message of the confirmation dialog when `showConfirmation` is `true`.\n *\n * @param index Index of the row being removed.\n */\n confirmDialogMessage?: (index: number) => ReactNode;\n /**\n * Ok button text of the confirmation dialog when `showConfirmation` is\n * `true`.\n */\n confirmDialogOkText?: ReactNode;\n /**\n * Cancel button text of the confirmation dialog when `showConfirmation` is\n * `true`.\n */\n confirmDialogCancelText?: ReactNode;\n /**\n * Whether to show the trigger when the table is read-only.\n *\n * @default false\n */\n showWhenReadOnly?: boolean;\n /**\n * Children of the remove row trigger component. By default, it is an\n * `IconButton` with label `defaultButtonLabel`. A function can be optionally\n * passed as children which will receive an argument with whether the row is\n * currently being removed.\n */\n children?: ReactNode;\n}\n\n/**\n * Trigger used to remove a row of a table controlled by a table control.\n *\n * By default, it renders an icon button with label `defaultButtonLabel`,\n * however, this can be overriden by providing `children`.\n */\nexport const TableControlRemoveRowTrigger = forwardRef<\n ComponentRef<typeof IconButton>,\n TableControlRemoveRowTriggerProps\n>(function TableControlRemoveRowTrigger(\n {\n showConfirmation,\n onConfirmRowRemoval,\n onRowRemoved,\n defaultButtonLabel,\n confirmDialogTitle,\n confirmDialogMessage,\n confirmDialogOkText,\n confirmDialogCancelText,\n showWhenReadOnly,\n disabled,\n onClick,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const [locale] = useLocale();\n defaultButtonLabel ??= locale.TableControlRemoveRowTrigger.defaultButtonLabel;\n confirmDialogTitle ??= locale.TableControlRemoveRowTrigger.confirmDialogTitle;\n confirmDialogMessage ??=\n locale.TableControlRemoveRowTrigger.confirmDialogMessage;\n confirmDialogOkText ??=\n locale.TableControlRemoveRowTrigger.confirmDialogOkText;\n confirmDialogCancelText ??=\n locale.TableControlRemoveRowTrigger.confirmDialogCancelText;\n\n const { confirm } = useAlertDialog();\n const { controller } = useTableControlContext();\n const controlIsDisabled = useFormIsDisabled();\n const controlIsReadOnly = useFormIsReadOnly();\n const { getState, index, useInitialized, useExists } =\n useTableControlRowContext();\n const initialized = useInitialized();\n const exists = useExists();\n const setLatestInteraction = useSetLatestInteraction();\n\n const [removing, setRemoving] = useState(false);\n const handleClick = async () => {\n const { path, dirty } = getState();\n if (\n removing ||\n (showConfirmation &&\n dirty &&\n !(await confirm(confirmDialogMessage!(index), {\n title: confirmDialogTitle,\n color: \"danger\",\n okText: confirmDialogOkText,\n cancelText: confirmDialogCancelText,\n })))\n ) {\n return;\n }\n\n setRemoving(true);\n onConfirmRowRemoval?.();\n await controller.removeRow(path);\n setLatestInteraction(controller.getState().path);\n onRowRemoved?.();\n };\n\n const As: any = Slot;\n return (\n (showWhenReadOnly || !controlIsReadOnly) && (\n <As\n {...otherProps}\n disabled={\n !initialized ||\n !exists ||\n controlIsDisabled ||\n disabled ||\n controlIsReadOnly ||\n removing\n }\n onClick={combineEventHandlers(onClick, handleClick, {\n checkDefaultPrevented: true,\n })}\n ref={forwardedRef}\n >\n {children ?? (\n <IconButton\n icon={faTrash}\n label={defaultButtonLabel}\n color=\"danger\"\n loading={!initialized || removing}\n circle\n />\n )}\n </As>\n )\n );\n});\n","import type { Controller } from \"@ostack.tech/kform-react\";\nimport type { DataTableColumn } from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { TableControlRemoveRowTrigger } from \"./TableControlRemoveRowTrigger.tsx\";\n\n/** Array of table control columns. */\nexport type TableControlColumns<T = unknown> = (\n | TableControlColumn<T>\n | ((\n tableControlStatus: TableControlStatus,\n ) => TableControlColumn<T> | false | null | undefined)\n | false\n | null\n | undefined\n)[];\n\n/** Status of the table control. */\nexport interface TableControlStatus {\n /** Whether the table control is disabled. */\n disabled: boolean;\n /** Whether the table control is read-only. */\n readOnly: boolean;\n /** Whether the table is being printed. */\n printing: boolean;\n}\n\n/** Controller of a table row. */\nexport type TableControlRowController<T = unknown> = Controller<T> & {\n /** Row index. */\n index: number;\n};\n\n/** Column of a table control. */\n\nexport interface TableControlColumn<T = unknown, TValue = any>\n extends Omit<\n DataTableColumn<T, TValue>,\n | \"subColumns\"\n | \"getValue\"\n | \"format\"\n | \"render\"\n | \"compare\"\n | \"filterable\"\n | \"sortable\"\n > {\n /** Sub columns of this column. */\n subColumns?: TableControlColumns<T>;\n /** Function used to render the cell's content. */\n render?: (rowController: TableControlRowController<T>) => ReactNode;\n}\n\n/**\n * Pre-configured column used to display the index of each row. By default, it\n * sticks to left of the table.\n *\n * @param overrides Column properties to override the defaults.\n * @returns Table control column used to display the index of each row.\n */\n\nexport function tableControlIndexColumn<T = unknown, TValue = any>(\n overrides?: TableControlColumn<T, TValue>,\n): TableControlColumn<T, TValue> {\n return {\n label: \"#\",\n header: true,\n sticky: \"left\",\n width: 65,\n fixed: true,\n align: \"center\",\n render: ({ index }) => index + 1,\n ...overrides,\n } as TableControlColumn<T, TValue>;\n}\n\n/**\n * Pre-configured column used to display row actions. By default, it sticks to\n * the right of the table and renders the `TableControlRemoveRow` component.\n *\n * Its configuration can be overriden to show other actions, for example, an\n * edit button:\n *\n * ```tsx\n * tableControlActionsColumn({\n * width: 100,\n * render: () => (\n * <>\n * <IconButton label=\"Edit row\" icon={faPencil} />\n * <TableControlRemoveRow />\n * </>\n * ),\n * });\n * ```\n *\n * @param overrides Column properties used to display the actions of each row.\n * @returns Table control column used to display the actions of each row.\n */\n\nexport function tableControlActionsColumn<T = unknown, TValue = any>({\n removeRowProps,\n ...columnOverrides\n}: TableControlColumn<T, TValue> & {\n removeRowProps?: ComponentPropsWithRef<typeof TableControlRemoveRowTrigger>;\n} = {}): (\n tableControlStatus: TableControlStatus,\n) => TableControlColumn<T, TValue> | false {\n return (tableControlStatus: TableControlStatus) =>\n !tableControlStatus.readOnly &&\n !tableControlStatus.printing &&\n ({\n sticky: \"right\",\n width: 50,\n fixed: true,\n align: \"center\",\n render: () => <TableControlRemoveRowTrigger {...removeRowProps} />,\n ...columnOverrides,\n } as TableControlColumn<T, TValue>);\n}\n","import {\n combineEventHandlers,\n cx,\n DataTableContent,\n useCombinedRef,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useDeferredValue,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useTableControlContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control content component. */\nexport interface TableControlContentProps\n extends Omit<ComponentPropsWithoutRef<typeof DataTableContent>, \"status\"> {}\n\n/** Component containing the content of the table control. */\nexport const TableControlContent = forwardRef<\n ComponentRef<typeof DataTableContent>,\n TableControlContentProps\n>(function TableControlContent(\n { containerProps, ...otherProps },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { autofocusRef, handleFocus, controller } = useTableControlContext();\n\n const handleContainerOnBlur = useCallback(() => {\n const { initialized, exists, touched } = controller.getState();\n if (initialized && exists && touched) {\n void controller.setTouched();\n }\n }, [controller]);\n\n const printing = usePrinting();\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n return (\n <DataTableContent\n editable\n variant=\"control\"\n status={\n printing\n ? undefined\n : displayStatusToControlStatus(deferredDisplayStatus)\n }\n containerProps={{\n ...containerProps,\n className: cx(\n prefix(\"table-control__content-container\"),\n containerProps?.className,\n ),\n onFocus: combineEventHandlers(containerProps?.onFocus, handleFocus),\n onBlur: combineEventHandlers(\n containerProps?.onBlur,\n handleContainerOnBlur,\n ),\n ref: useCombinedRef(autofocusRef, containerProps?.ref),\n }}\n {...otherProps}\n ref={forwardedRef}\n />\n );\n});\n","import { DataTablePagination } from \"@ostack.tech/ui\";\n\n/** Table control pagination. */\nexport const TableControlPagination = DataTablePagination;\n","import { DataTableRowsPerPage } from \"@ostack.tech/ui\";\n\n/** Table control rows per page. */\nexport const TableControlRowsPerPage = DataTableRowsPerPage;\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n InvalidPathError,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n Input,\n TextArea,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the text control component. */\nexport type TextControlProps<T extends string | null = string | null> =\n | TextControlPropsSingleline<T>\n | TextControlPropsMultiline<T>;\n\nexport type TextControlPropsSingleline<\n T extends string | null = string | null,\n> = Omit<\n ComponentPropsWithoutRef<typeof Input>,\n \"defaultValue\" | \"value\" | \"status\"\n> &\n TextControlPropsBase<T> & {\n multiline?: false;\n };\n\nexport type TextControlPropsMultiline<T extends string | null = string | null> =\n Omit<\n ComponentPropsWithoutRef<typeof TextArea>,\n \"defaultValue\" | \"value\" | \"status\"\n > &\n TextControlPropsBase<T> & {\n multiline: true;\n pattern?: never;\n };\n\nexport type TextControlPropsBase<T extends string | null = string | null> =\n Omit<\n InputOptions<T, string, ComponentRef<typeof Input | typeof TextArea>>,\n \"enabled\" | \"format\" | \"parse\"\n > & {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control\n * to be focused when the form app's `focus` is called with this control's\n * path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Whether to render a multiline text control. */\n multiline?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | InputController<T, string, ComponentRef<typeof Input | typeof TextArea>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\"\n >;\n };\n\n/**\n * Text control component supporting (possibly nullable) schemas of type\n * \"String\".\n *\n * If the schema is nullable, this component sets the form value to `null` when\n * the control is empty. Note, however, that the form may still hold an empty\n * string as value if set programmatically.\n *\n * The component further supports either single or multiple lines via the\n * `multiline` prop.\n */\nexport const TextControl = forwardRef(function TextControl<\n T extends string | null = string | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n multiline,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n minLength,\n maxLength,\n pattern,\n loading,\n disabled,\n readOnly,\n endAdornment,\n onChange,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: TextControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<\"input\" | \"textarea\">>,\n) {\n const controller = useInput<T, string, ComponentRef<typeof Input>>(path, {\n enabled: !useFormIsLoading(),\n parse: parseText,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n if (schema.typeInfo.name !== \"String\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n \"strings, but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const prevMultiline = useRef(multiline);\n useEffect(() => {\n if (prevMultiline.current !== multiline) {\n throw new Error(\n \"The `multiline` property cannot not be changed at runtime.\",\n );\n }\n }, [multiline]);\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const commonProps: ComponentPropsWithRef<typeof Input | typeof TextArea> = {\n name: inputProps.name,\n required: required ?? restrictions.required === true,\n minLength:\n minLength ??\n (typeof restrictions.minLength === \"number\"\n ? restrictions.minLength\n : undefined),\n maxLength:\n maxLength ??\n (typeof restrictions.maxLength === \"number\"\n ? restrictions.maxLength\n : undefined),\n pattern:\n pattern ??\n (typeof restrictions.pattern === \"string\"\n ? restrictions.pattern\n : undefined),\n loading: displayLoading || loading,\n disabled: displayDisabled || disabled,\n readOnly: displayReadOnly || readOnly || inputProps.readOnly,\n status: displayStatusToControlStatus(displayStatusToDisplay),\n endAdornment: (\n <>\n {popoverIssues}\n {endAdornment}\n </>\n ),\n onChange: combineEventHandlers(onChange as never, inputProps.onChange),\n onFocus: combineEventHandlers(onFocus as never, handleFocus),\n onBlurToOutside: combineEventHandlers(\n onBlurToOutside as never,\n inputProps.onBlur,\n ),\n ref: useCombinedRef(\n inputProps.ref,\n useCombinedRef(autofocusRef, forwardedRef),\n ) as never,\n ...otherProps,\n };\n return (\n <>\n {multiline ? (\n <TextArea\n {...(commonProps as ComponentPropsWithRef<typeof TextArea>)}\n />\n ) : (\n <Input\n type=\"text\"\n {...(commonProps as ComponentPropsWithRef<typeof Input>)}\n />\n )}\n {inlineIssues}\n </>\n );\n});\n\n/** Parses a text control formatted value. */\nfunction parseText<T extends string | null>(\n formattedValue: string,\n state: FormatterControllerState<T, string>,\n): T {\n return (\n state.schema.typeInfo.nullable ? formattedValue || null : formattedValue\n ) as T;\n}\n","import {\n cx,\n PortalContext,\n useCombinedRef,\n useMeasure,\n usePrintClassNames,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useSetTopBarHeight } from \"../FormApp\";\n\n/** Properties of the top bar component. */\nexport interface TopBarProps extends ComponentPropsWithoutRef<\"div\"> {}\n\n/** Top bar component. */\nexport const TopBar = forwardRef<ComponentRef<\"div\">, TopBarProps>(\n function TopBar({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n const { printHidden } = usePrintClassNames();\n const setTopBarHeight = useSetTopBarHeight();\n\n const [topBarEl, setTopBarEl] = useState<HTMLDivElement | null>(null);\n useMeasure(\n topBarEl,\n useCallback(\n (measurement) => setTopBarHeight(measurement?.height),\n [setTopBarHeight],\n ),\n );\n\n const combinedTopBarRef = useCombinedRef(setTopBarEl, forwardedRef);\n return (\n <PortalContext.Provider value={{ container: topBarEl }}>\n <div\n className={cx(prefix(\"top-bar\"), printHidden, className)}\n {...otherProps}\n ref={combinedTopBarRef}\n />\n </PortalContext.Provider>\n );\n },\n);\n","import { cx, Stack } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\n\n/** Properties of the top bar actions component. */\nexport interface TopBarActionsProps\n extends ComponentPropsWithoutRef<typeof Stack> {}\n\n/** Container used to display actions within the top bar. */\nexport const TopBarActions = forwardRef<\n ComponentRef<typeof Stack>,\n TopBarActionsProps\n>(function TopBarActions({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n\n return (\n <Stack\n className={cx(prefix(\"top-bar__actions\"), className)}\n direction=\"row\"\n gap={2}\n justifyContent=\"flex-end\"\n {...otherProps}\n ref={forwardedRef}\n />\n );\n});\n","import { faCircleCheck } from \"@fortawesome/free-regular-svg-icons\";\nimport {\n Button,\n type ButtonProps,\n combineEventHandlers,\n useKeyboardShortcut,\n} from \"@ostack.tech/ui\";\nimport { type ReactNode, useDeferredValue } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport {\n useFormIsValidating,\n useFormValidator,\n} from \"../../utils/useFormValidator.ts\";\nimport { useFormAppElement, useFormIsDisabled } from \"../FormApp\";\n\n/** Properties of the validate action. */\nexport interface ValidateActionProps extends Omit<ButtonProps, \"children\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n}\n\n/** Action used to validate the form. */\nexport function ValidateAction({\n label,\n keybinds,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n ...otherProps\n}: ValidateActionProps) {\n const [locale] = useLocale();\n label ??= locale.ValidateAction.label;\n keybinds ??= locale.ValidateAction.keybinds;\n\n const { validate } = useFormValidator();\n const { validatingAutomatically, validatingManually, validating } =\n useFormIsValidating();\n const deferredValidating = useDeferredValue(validating);\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading ||\n validatingManually;\n\n // Set-up keyboard shortcut\n const formAppEl = useFormAppElement();\n useKeyboardShortcut(keybinds, validate, {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <Button\n color=\"primary\"\n icon={faCircleCheck}\n vertical\n {...otherProps}\n onClick={combineEventHandlers(validate, onClick as never)}\n disabled={shouldDisable}\n loading={loading || deferredValidating}\n enabledWhenLoading={enabledWhenLoading || validatingAutomatically}\n >\n {label}\n </Button>\n );\n}\n"],"names":["useUiPrefix","defaultPrefixSuffix","activePath","locale","UiLocalizationProvider","focusedPath","controller","FormAppElement","FormApp","mostSpecific","activeAnnex","Annex","state","AnnexTabContent","decode","path","extensions","mimeTypes","description","startIn","id","setPristineOnLoad","validateOnLoad","successMessage","errorMessage","value","Annexes","ControlField","formManager","IssueMessages","info","IssuesPopover","removeAnnex","canBeAdded","AnnexManager","useState","CheckboxControl","key","i","CheckboxGroupControl","formattedValue","arrayValue","min","max","format","fnsFormat","DateControl","DateRangeControl","FileControl","activePage","FormPageHeader","FormPage","FormPages","FormPagesSelect","FormPagesSidebar","FormPagesNavigation","activeStep","FormStepContent","FormStepper","IssueMessage","IssuesPanelMessagesCard","IssuesPanelSummaryCard","NumericControl","stringValue","RadioGroupControl","overwrite","encode","fileName","excludeAcceptAllOption","setPristineOnSave","SelectControl","options","SelectMultipleControl","TableControlCell","TableControlRow","TableControl","schema","initialized","exists","TableControlAddRowTrigger","TableControlRemoveRowTrigger","TableControlContent","TextControl","TopBar","TopBarActions","faCircleCheck"],"mappings":"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"}
1
+ {"version":3,"file":"ostack-ui-kform.js","sources":["../src/providers/PrefixSuffixProvider/defaultPrefixSuffix.ts","../src/providers/PrefixSuffixProvider/PrefixSuffixContext.ts","../src/providers/PrefixSuffixProvider/PrefixSuffixProvider.tsx","../src/providers/PrefixSuffixProvider/usePrefix.ts","../src/providers/ActivePathProvider/ActivePathContext.ts","../src/providers/ActivePathProvider/ActivePathProvider.tsx","../src/providers/LocalizationProvider/LocalizationContext.ts","../src/providers/LocalizationProvider/LocalizationProvider.tsx","../src/providers/LocalizationProvider/useLocale.ts","../src/utils/pathSpecificity.ts","../src/utils/useEqualityFn.ts","../src/components/FormApp/FormAppContext.ts","../src/utils/useControlAutofocus.ts","../src/components/FormApp/FormAppAutoFocus.tsx","../src/components/FormApp/FormAppElement.tsx","../src/components/FormApp/FormAppIssueMessages.tsx","../src/components/FormApp/FormApp.tsx","../src/components/FormApp/FormAppStatus.tsx","../src/utils/mostSpecificPath.ts","../src/components/Annexes/AnnexesContext.ts","../src/components/Annexes/Annex.tsx","../src/utils/useFormLoader.tsx","../src/components/Annexes/AnnexRegistrar.tsx","../src/components/Annexes/RepetitiveAnnexRegistrar.tsx","../src/components/Annexes/Annexes.tsx","../src/utils/useReportValidationFailures.ts","../src/components/ControlField/ControlFieldContext.ts","../src/components/ControlField/ControlField.tsx","../src/components/IssueMessage/IssueMessage.tsx","../src/components/IssueMessages/IssueMessages.tsx","../src/components/IssuesPopover/IssuesPopover.tsx","../src/utils/displayStatusConversions.ts","../src/components/Annexes/AnnexesMenu.tsx","../src/components/Annexes/AnnexTab.tsx","../src/components/Annexes/AnnexesTabList.tsx","../src/components/Annexes/AnnexesManager.tsx","../src/utils/useControlIssues.tsx","../src/utils/useRegisterControl.tsx","../src/components/CheckboxControl/CheckboxControl.tsx","../src/utils/selectionTransformations.tsx","../src/components/CheckboxGroupControl/CheckboxGroupControl.tsx","../src/utils/dateRestrictions.ts","../src/utils/useTemporalStringTransformer.ts","../src/components/DateControl/DateControl.tsx","../src/components/DateRangeControl/DateRangeControl.tsx","../src/components/FileControl/FileControl.tsx","../src/components/FormPages/FormPagesContext.ts","../src/components/FormPages/FormPageHeader.tsx","../src/components/FormPages/FormPage.tsx","../src/components/FormPages/FormPageRegistrar.tsx","../src/components/FormPages/FormPages.tsx","../src/components/FormPages/FormPagesSelectOption.tsx","../src/components/FormPages/FormPagesSelect.tsx","../src/components/FormPages/FormPageSidebarItem.tsx","../src/components/FormPages/FormPagesSidebar.tsx","../src/components/FormPages/FormPagesNavigation.tsx","../src/components/FormStepper/FormStepperContext.ts","../src/components/FormStepper/FormStepContent.tsx","../src/components/FormStepper/FormStep.tsx","../src/components/FormStepper/FormStepList.tsx","../src/components/FormStepper/FormStepRegistrar.tsx","../src/components/FormStepper/FormStepper.tsx","../src/components/IssueAlert/IssueAlert.tsx","../src/utils/useFormValidator.ts","../src/components/IssuesPanel/IssuesPanelControls.tsx","../src/components/IssuesPanel/IssuesPanelMessagesCard.tsx","../src/components/IssuesPanel/IssuesPanelSummaryCard.tsx","../src/components/IssuesPanel/IssuesPanel.tsx","../src/components/LoadAction/LoadAction.tsx","../src/components/NumericControl/NumericControl.tsx","../src/components/PathLink/PathLink.tsx","../src/components/PrintAction/PrintAction.tsx","../src/components/RadioGroupControl/RadioGroupControl.tsx","../src/utils/useFormSaver.tsx","../src/components/SaveAction/SaveAction.tsx","../src/components/SelectControl/SelectControl.tsx","../src/components/SelectMultipleControl/SelectMultipleControl.tsx","../src/components/SubmitAction/SubmitAction.tsx","../src/components/TableControl/TableControlContext.ts","../src/components/TableControl/TableControlCell.tsx","../src/components/TableControl/TableControlRow.tsx","../src/components/TableControl/TableControl.tsx","../src/components/TableControl/TableControlAddRowTrigger.tsx","../src/components/TableControl/TableControlApi.ts","../src/components/TableControl/TableControlRemoveRowTrigger.tsx","../src/components/TableControl/TableControlColumn.tsx","../src/components/TableControl/TableControlContent.tsx","../src/components/TableControl/TableControlPagination.tsx","../src/components/TableControl/TableControlRowsPerPage.tsx","../src/components/TextControl/TextControl.tsx","../src/components/TopBar/TopBar.tsx","../src/components/TopBar/TopBarActions.tsx","../src/components/ValidateAction/ValidateAction.tsx"],"sourcesContent":["import { createStore } from \"zustand\";\n\n/** Initial default library prefix-suffix. */\nconst DEFAULT_PREFIX_SUFFIX = \"kform-\";\n\n/** Store holding the default prefix-suffix. */\nexport const defaultPrefixSuffixStore = createStore(() => ({\n defaultPrefixSuffix: DEFAULT_PREFIX_SUFFIX,\n}));\n\n/**\n * Function used to set the default library's prefix-suffix. The default library\n * prefix-suffix can be overridden by providing a `prefixSuffix` property to the\n * `PrefixSuffixProvider` or `FormApp` components.\n *\n * @param defaultPrefixSuffix Prefix-suffix to set as the library's default.\n */\nexport function setDefaultPrefixSuffix(defaultPrefixSuffix: string) {\n defaultPrefixSuffixStore.setState({ defaultPrefixSuffix });\n}\n","import { createContext } from \"react\";\n\n/** Prefix-suffix context. */\nexport const PrefixSuffixContext = createContext<string | null>(null);\n","import type { ReactNode } from \"react\";\n\nimport { PrefixSuffixContext } from \"./PrefixSuffixContext.ts\";\n\n/** Properties of the prefix-suffix provider. */\nexport interface PrefixSuffixProviderProps {\n /** Suffix to add to ostack/UI's prefix. */\n prefixSuffix?: string;\n children: ReactNode;\n}\n\n/** Prefix-suffix provider. */\nexport function PrefixSuffixProvider({\n prefixSuffix,\n children,\n}: PrefixSuffixProviderProps) {\n return prefixSuffix === undefined ? (\n children\n ) : (\n <PrefixSuffixContext.Provider value={prefixSuffix}>\n {children}\n </PrefixSuffixContext.Provider>\n );\n}\n","import { type PrefixFn, usePrefix as useUiPrefix } from \"@ostack.tech/ui\";\nimport { useCallback, useContext } from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { defaultPrefixSuffixStore } from \"./defaultPrefixSuffix.ts\";\nimport { PrefixSuffixContext } from \"./PrefixSuffixContext.ts\";\n\n/**\n * Hook which returns a function which can be used to prefix a string with the\n * current prefix.\n */\nexport function usePrefix(): PrefixFn {\n const prefix = useUiPrefix();\n const defaultPrefixSuffix = useStore(\n defaultPrefixSuffixStore,\n ({ defaultPrefixSuffix }) => defaultPrefixSuffix,\n );\n const prefixSuffix = useContext(PrefixSuffixContext) ?? defaultPrefixSuffix;\n return useCallback(\n (toPrefix = \"\") => prefix(`${prefixSuffix}${toPrefix}`),\n [prefix, prefixSuffix],\n );\n}\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { createContext, useContext } from \"react\";\n\n/** Value of the active path context. */\nexport interface ActivePathContextValue {\n activePath: AbsolutePath;\n onActivePathChange: (activePath: AbsolutePath | string | null) => void;\n}\n\n/** Active path context. */\nexport const ActivePathContext = createContext<ActivePathContextValue | null>(\n null,\n);\n\n/** Hook providing access to the active path context. */\nexport function useActivePathContext(): ActivePathContextValue {\n const activePathContext = useContext(ActivePathContext);\n if (!activePathContext) {\n throw new Error(\"Active path context not in scope\");\n }\n return activePathContext;\n}\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n type Path,\n} from \"@ostack.tech/kform\";\nimport { useResolvedPath } from \"@ostack.tech/kform-react\";\nimport { useControllableState, useLatestValues } from \"@ostack.tech/ui\";\nimport { type ReactNode, useCallback, useMemo } from \"react\";\n\nimport { ActivePathContext } from \"./ActivePathContext.ts\";\n\n/**\n * Navigation options to use when controlling the active path via the browser's\n * URL.\n */\nexport interface OnActivePathChangeNavigationOptions {\n /** Whether to replace the current history entry. */\n replace: boolean;\n}\n\n/** Properties of the active path provider. */\nexport interface ActivePathProviderProps {\n /** Uncontrolled default active path to use. */\n defaultActivePath?: string | Path;\n /** Controlled active path to use. */\n activePath?: string | Path;\n /**\n * Callback called whenever the active path is changed.\n *\n * @param activePath New active path.\n * @param options Navigation options to use when controlling the active path\n * via the browser's URL.\n */\n onActivePathChange?: (\n activePath: AbsolutePath,\n options: OnActivePathChangeNavigationOptions,\n ) => void;\n children?: ReactNode;\n}\n\n/** Provider which controls the active path in a section of a form. */\nexport function ActivePathProvider({\n defaultActivePath,\n activePath: controlledActivePath,\n onActivePathChange,\n children,\n}: ActivePathProviderProps) {\n const [activePath, setActivePath] = useControllableState(\n defaultActivePath,\n controlledActivePath,\n );\n const resolvedActivePath = useResolvedPath(activePath);\n\n const latest = useLatestValues({ resolvedActivePath, onActivePathChange });\n const handleActivePathChange = useCallback(\n (newActivePath: AbsolutePath | string | null) => {\n const activePath = latest.resolvedActivePath;\n if (typeof newActivePath === \"string\") {\n newActivePath = new AbsolutePath(newActivePath);\n } else {\n newActivePath ??= AbsolutePath.ROOT;\n }\n\n // Ignore when new path is equal to or an ancestor of the old one\n if (\n !activePath.equals(newActivePath) &&\n !newActivePath\n .append(AbsolutePathFragment.RecursiveWildcard)\n .contains(activePath)\n ) {\n // Replace when the old path is an ancestor of the new one\n const replace = activePath\n .append(AbsolutePathFragment.RecursiveWildcard)\n .contains(newActivePath);\n setActivePath(newActivePath);\n latest.onActivePathChange?.(newActivePath, { replace });\n }\n },\n [latest, setActivePath],\n );\n\n return (\n <ActivePathContext.Provider\n value={useMemo(\n () => ({\n activePath: resolvedActivePath,\n onActivePathChange: handleActivePathChange,\n }),\n [handleActivePathChange, resolvedActivePath],\n )}\n >\n {children}\n </ActivePathContext.Provider>\n );\n}\n","import { createContext } from \"react\";\n\nimport type { LocalizationObject } from \"./LocalizationObject.ts\";\n\n/** Value of the localisation context. */\nexport interface LocalizationContextValue {\n locale: LocalizationObject;\n setLocale: (locale: LocalizationObject) => void;\n}\n\n/** Localisation context. */\nexport const LocalizationContext =\n createContext<LocalizationContextValue | null>(null);\n","import {\n combineEventHandlers,\n LocalizationProvider as UiLocalizationProvider,\n useControllableState,\n} from \"@ostack.tech/ui\";\nimport type { ReactNode } from \"react\";\n\nimport { LocalizationContext } from \"./LocalizationContext.ts\";\nimport type { LocalizationObject } from \"./LocalizationObject.ts\";\n\n/** Properties of the localisation provider. */\nexport interface LocalizationProviderProps {\n /** Uncontrolled locale to use. */\n defaultLocale?: LocalizationObject;\n /** Controlled locale to use. */\n locale?: LocalizationObject;\n /**\n * Function called when the locale changes.\n *\n * @param locale New locale.\n */\n onLocaleChange?: (locale: LocalizationObject) => void;\n children: ReactNode;\n}\n\n/**\n * Localisation provider (also sets the `@ostack.tech/ui` localisation\n * provider).\n */\nexport function LocalizationProvider({\n defaultLocale,\n locale: controlledLocale,\n onLocaleChange,\n children,\n}: LocalizationProviderProps) {\n const [locale, setLocale] = useControllableState(\n defaultLocale,\n controlledLocale,\n );\n\n return locale === undefined ? (\n children\n ) : (\n <LocalizationContext.Provider\n value={{\n locale,\n setLocale: combineEventHandlers(setLocale, onLocaleChange),\n }}\n >\n <UiLocalizationProvider locale={locale.baseLocale}>\n {children}\n </UiLocalizationProvider>\n </LocalizationContext.Provider>\n );\n}\n","import { useContext, useMemo } from \"react\";\n\nimport { LocalizationContext } from \"./LocalizationContext.ts\";\nimport type { LocalizationObject } from \"./LocalizationObject.ts\";\n\n/** Hook used to get and set the current locale. */\nexport function useLocale(): [\n LocalizationObject,\n (locale: LocalizationObject) => void,\n] {\n const localizationContext = useContext(LocalizationContext);\n if (localizationContext === null)\n throw new Error(\n \"No locale has been provided. Please provide a locale via the \" +\n \"`FormApp` or `LocalizationProvider` components.\",\n );\n return useMemo(\n () => [localizationContext.locale, localizationContext.setLocale],\n [localizationContext.locale, localizationContext.setLocale],\n );\n}\n","import { type AbsolutePath, AbsolutePathFragment } from \"@ostack.tech/kform\";\n\ntype PathSpecificity = [number, number, number];\n\n/**\n * Given two paths, returns a number > 0 if the first path is more specific than\n * the second, a number < 0 if the first path is less specific than the second,\n * or 0 if both paths have the same specificity.\n *\n * Specificity is not incredibly well specified (and may change over time if a\n * need arises), but the idea is that wildcards make paths less specific, so\n * `/a/∗` is less specific than `/a/b`, and `/∗∗` is the least specific path.\n *\n * Both `/a` and `/a/b/c` have the same specificity since both paths uniquely\n * identify a resource.\n *\n * @param path1 First path to compare.\n * @param path2 Second path to compare.\n * @returns Number representing which path is more specific.\n */\nexport function comparePathsBySpecificity(\n path1: AbsolutePath,\n path2: AbsolutePath,\n) {\n const [ids1, wildcards1, recursiveWildcards1] = pathSpecificity(path1);\n const [ids2, wildcards2, recursiveWildcards2] = pathSpecificity(path2);\n // When neither path has recursive wildcards, the most specific one is the one\n // with the least non-recursive wildcards\n if (recursiveWildcards1 === 0 && recursiveWildcards2 === 0) {\n return wildcards2 - wildcards1;\n }\n // When one path has recursive wildcards but the other one doesn't, the most\n // specific one is the one without recursive wildcards\n if (recursiveWildcards1 === 0 || recursiveWildcards2 === 0) {\n return recursiveWildcards2 - recursiveWildcards1;\n }\n // When both paths have recursive wildcards, the most specific one is the one\n // with the most identifiers; if the number of identifiers is the same, then\n // the one with the most non-recursive wildcards\n return ids1 - ids2 || wildcards1 - wildcards2;\n}\n\nfunction pathSpecificity(path: AbsolutePath): PathSpecificity {\n const specificity: PathSpecificity = [0, 0, 0];\n for (const fragment of path.fragments) {\n if (fragment instanceof AbsolutePathFragment.Id) {\n ++specificity[0];\n } else if (fragment === AbsolutePathFragment.Wildcard) {\n ++specificity[1];\n } else if (fragment === AbsolutePathFragment.RecursiveWildcard) {\n ++specificity[2];\n }\n }\n return specificity;\n}\n","import { useRef } from \"react\";\n\nconst INITIAL = Symbol();\n\n// TODO: This is repeated both here and in `@ostack.tech/kform-react`, it might\n// make sense to either export and use the `@ostack.tech/kform-react` version\n// or upstream it instead\nexport function useEqualityFn<TState, TResult>(\n selector: (state: TState) => TResult,\n equalityFn: (v1: TResult, v2: TResult) => boolean = Object.is,\n): (state: TState) => TResult {\n const latest = useRef<TResult | typeof INITIAL>(INITIAL);\n return (state) => {\n const next = selector(state);\n return latest.current !== INITIAL && equalityFn(latest.current, next)\n ? latest.current\n : (latest.current = next);\n };\n}\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n type Path,\n PathMultimap,\n type PathMultimapEntryId,\n} from \"@ostack.tech/kform\";\nimport { type Controller, equals } from \"@ostack.tech/kform-react\";\nimport { useConstant, useLatestValues, usePrinting } from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { useShallow } from \"zustand/react/shallow\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { comparePathsBySpecificity } from \"../../utils/pathSpecificity.ts\";\nimport { useEqualityFn } from \"../../utils/useEqualityFn.ts\";\nimport type { IssueMessagesByCode, IssueMessageValue } from \"../IssueMessages\";\nimport type { IssuesDisplayMode } from \"./FormApp.tsx\";\n\n/** Value of the form app context. */\nexport interface FormAppContextValue<T = unknown> {\n formTitle?: string;\n disabled: boolean;\n readOnly: boolean;\n issuesDisplayMode: IssuesDisplayMode;\n displayIssueCodes: boolean;\n formAppElement: HTMLFormElement | null;\n store: FormAppStore<T>;\n}\n\n/** State of the form app. */\nexport interface FormAppState<T> {\n controller: Controller<T>;\n focusedPath: AbsolutePath | null;\n focusCounter: number;\n issuesPanelPath: AbsolutePath | null;\n topBarHeight: number;\n leftSidebarWidth: number;\n bottomPanelHeight: number;\n startIssuesNavigation?: () => void;\n latestInteraction: AbsolutePath;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new multimap\n // instances\n registeredControllers: [PathMultimap<Controller>];\n registeredIssueMessages: [\n PathMultimap<{ messages: IssueMessagesByCode; priority: number }>,\n ];\n deferredIssueMessageRemovalEntryIds: PathMultimapEntryId[];\n registeredLabels: [PathMultimap<{ label: ReactNode; priority: number }>];\n deferredLabelRemovalEntryIds: PathMultimapEntryId[];\n actions: FormAppActions;\n}\n\n/** Item of a breadcrumb. */\nexport interface BreadcrumbItem {\n path: AbsolutePath;\n label: ReactNode;\n}\n\n/** Actions of the form app. */\nexport interface FormAppActions {\n setIssuesPanelPath: (path: AbsolutePath | null) => void;\n focus: (path: string | Path) => void;\n resetFocus: () => void;\n registerController: (\n path: AbsolutePath,\n controller?: Controller<any> | null,\n ) => (() => void) | void;\n isRegistered: (path: AbsolutePath) => boolean;\n setLatestInteraction: (path: AbsolutePath) => void;\n registerIssueMessages: (\n basePath: AbsolutePath,\n issueMessages?: Record<string, IssueMessagesByCode>,\n priority?: number,\n ) => (() => void) | void;\n getRegisteredIssueMessage: (\n path: AbsolutePath,\n code: string,\n ) => IssueMessageValue | null;\n registerLabel: (\n path: AbsolutePath,\n label: ReactNode,\n priority?: number,\n ) => (() => void) | void;\n getRegisteredLabel: (path: AbsolutePath) => ReactNode;\n getActiveIssuesPanelBreadcrumb: () => BreadcrumbItem[] | null;\n startIssuesNavigation: (options?: {\n validate?: boolean;\n setTouched?: boolean;\n }) => PromiseLike<void>;\n}\n\n/** Form app store. */\nexport type FormAppStore<T> = ReturnType<\n typeof useCreateFormAppContext<T>\n>[\"store\"];\n\n/** Form app context. */\nexport const FormAppContext = createContext<FormAppContextValue | null>(null);\n\n/** Options used to create the data table context value. */\nexport interface UseCreateFormAppContextOptions<T> extends Omit<\n FormAppContextValue<T>,\n \"store\"\n> {\n controller: Controller<T>;\n onPathFocus?: (path: AbsolutePath) => void;\n}\n\n/** Hook which creates the form app context. */\nexport function useCreateFormAppContext<T>({\n formTitle,\n controller,\n disabled,\n readOnly,\n issuesDisplayMode,\n displayIssueCodes,\n formAppElement,\n onPathFocus,\n}: UseCreateFormAppContextOptions<T>) {\n const latest = useLatestValues({ printing: usePrinting(), onPathFocus });\n\n const store = useConstant(() =>\n createStore<FormAppState<T>>()(\n subscribeWithSelector((set, get) => ({\n controller,\n focusedPath: null,\n focusCounter: 0,\n issuesPanelPath: null,\n topBarHeight: 0,\n leftSidebarWidth: 0,\n bottomPanelHeight: 0,\n startIssuesNavigation: undefined,\n latestInteraction: AbsolutePath.ROOT,\n registeredControllers: [new PathMultimap()],\n registeredIssueMessages: [new PathMultimap()],\n deferredIssueMessageRemovalEntryIds: [],\n registeredLabels: [new PathMultimap()],\n deferredLabelRemovalEntryIds: [],\n actions: {\n setIssuesPanelPath: (path: AbsolutePath | null) => {\n if (latest.printing) {\n return;\n }\n\n // Remove entries whose removal was deferred\n const {\n deferredIssueMessageRemovalEntryIds,\n deferredLabelRemovalEntryIds,\n } = get();\n if (deferredIssueMessageRemovalEntryIds.length > 0) {\n const [registeredIssueMessages] = get().registeredIssueMessages;\n for (const entryId of deferredIssueMessageRemovalEntryIds) {\n registeredIssueMessages.removeEntry(entryId);\n }\n set({ registeredIssueMessages: [registeredIssueMessages] });\n }\n if (deferredLabelRemovalEntryIds.length > 0) {\n const [registeredLabels] = get().registeredLabels;\n for (const entryId of deferredLabelRemovalEntryIds) {\n registeredLabels.removeEntry(entryId);\n }\n set({ registeredLabels: [registeredLabels] });\n }\n\n set({ issuesPanelPath: path });\n },\n getActiveIssuesPanelBreadcrumb: () => {\n const { issuesPanelPath, actions } = get();\n if (issuesPanelPath === null) {\n return null;\n }\n const breadcrumbParts: BreadcrumbItem[] = [];\n for (let i = 0; i <= issuesPanelPath.size; ++i) {\n const path =\n i === 0\n ? AbsolutePath.ROOT\n : i === issuesPanelPath.size\n ? issuesPanelPath\n : new AbsolutePath(issuesPanelPath.fragments.slice(0, i));\n const breadcrumb = actions.getRegisteredLabel(path);\n // if (!breadcrumb && process.env.NODE_ENV !== \"production\") {\n // warnOnce(`No label registered for path '${path.toString()}'.`);\n // }\n breadcrumbParts.push({\n path,\n label:\n breadcrumb ??\n (\n issuesPanelPath.fragment(\n i - 1,\n ) as AbsolutePathFragment.Id | null\n )?.id,\n });\n }\n return breadcrumbParts;\n },\n focus: (path: string | Path) => {\n if (latest.printing) {\n return;\n }\n\n const { focusedPath } = get();\n const absolutePath =\n path instanceof AbsolutePath ? path : new AbsolutePath(path);\n // Refuse non-existent paths\n if (\n !get().controller.getState().formManager.isValidPath(absolutePath)\n ) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Path to focus must only contain ids.\");\n }\n\n const focusPathChanged = !equals(focusedPath, absolutePath);\n set(({ focusedPath, focusCounter }) => ({\n focusedPath: focusPathChanged ? absolutePath : focusedPath,\n focusCounter: focusCounter + 1,\n }));\n if (focusPathChanged) {\n latest.onPathFocus?.(absolutePath);\n }\n },\n resetFocus: () => {\n if (!latest.printing) {\n set({ focusedPath: null });\n }\n },\n registerController: (\n path: AbsolutePath,\n controller?: Controller | null,\n ) => {\n if (controller == null) {\n return;\n }\n\n const [registeredControllers] = get().registeredControllers;\n const addedEntry = registeredControllers.put(path, controller);\n set(() => ({ registeredControllers: [registeredControllers] }));\n\n return () => {\n registeredControllers.removeEntry(addedEntry);\n set(() => ({ registeredControllers: [registeredControllers] }));\n };\n },\n isRegistered: (path: AbsolutePath) =>\n get().registeredControllers[0].containsPath(path),\n setLatestInteraction: (path: AbsolutePath) => {\n if (!latest.printing) {\n set({ latestInteraction: path });\n }\n },\n registerIssueMessages: (\n basePath: AbsolutePath,\n issueMessages?: Record<string, IssueMessagesByCode>,\n priority = 0,\n ) => {\n if (issueMessages == null) {\n return;\n }\n\n const [registeredIssueMessages] = get().registeredIssueMessages;\n const addedEntryIds: PathMultimapEntryId[] = [];\n for (const [path, issueMessagesByCode] of Object.entries(\n issueMessages,\n )) {\n addedEntryIds.push(\n registeredIssueMessages.put(basePath.resolve(path), {\n messages: issueMessagesByCode,\n priority,\n }),\n );\n }\n set(() => ({\n registeredIssueMessages: [registeredIssueMessages],\n }));\n\n return () => {\n const { issuesPanelPath } = get();\n for (const entryId of addedEntryIds) {\n // If the message being unregistered is currently in use by the\n // issues panel, defer its removal\n if (\n issuesPanelPath &&\n registeredIssueMessages\n .getEntry(entryId)!\n .path.append(AbsolutePathFragment.RecursiveWildcard)\n .contains(issuesPanelPath)\n ) {\n get().deferredIssueMessageRemovalEntryIds.push(entryId);\n } else {\n registeredIssueMessages.removeEntry(entryId);\n }\n }\n set(() => ({\n registeredIssueMessages: [registeredIssueMessages],\n }));\n };\n },\n getRegisteredIssueMessage: (path: AbsolutePath, code: string) => {\n const [registeredIssueMessages] = get().registeredIssueMessages;\n\n // Find the match with the most specific path\n let bestMatch = null;\n for (const entry of registeredIssueMessages.entries(path)) {\n if (entry.value.messages[code] == null) {\n continue;\n }\n\n const diff =\n bestMatch &&\n comparePathsBySpecificity(bestMatch.path, entry.path);\n if (\n bestMatch == null ||\n diff! < 0 ||\n // Larger priority wins\n (diff === 0 &&\n entry.value.priority > bestMatch.value.priority) ||\n // Last inserted wins\n (diff === 0 &&\n entry.value.priority === bestMatch.value.priority &&\n entry.id > bestMatch.id)\n ) {\n bestMatch = entry;\n }\n }\n return bestMatch?.value.messages[code] ?? null;\n },\n registerLabel: (\n path: AbsolutePath,\n label: ReactNode,\n priority = 0,\n ) => {\n if (!label) {\n return;\n }\n\n const [registeredLabels] = get().registeredLabels;\n const addedEntry = registeredLabels.put(path, { label, priority });\n set(() => ({ registeredLabels: [registeredLabels] }));\n\n return () => {\n const { issuesPanelPath } = get();\n // If the label being unregistered is currently in use by the\n // issues panel, defer its removal\n if (\n issuesPanelPath &&\n registeredLabels\n .getEntry(addedEntry)!\n .path.append(AbsolutePathFragment.RecursiveWildcard)\n .contains(issuesPanelPath)\n ) {\n get().deferredLabelRemovalEntryIds.push(addedEntry);\n } else {\n registeredLabels.removeEntry(addedEntry);\n }\n set(() => ({ registeredLabels: [registeredLabels] }));\n };\n },\n getRegisteredLabel: (path: AbsolutePath) => {\n const [registeredLabels] = get().registeredLabels;\n\n // Find the match with the most specific path\n let bestMatch = null;\n for (const entry of registeredLabels.entries(path)) {\n const diff =\n bestMatch &&\n comparePathsBySpecificity(bestMatch.path, entry.path);\n if (\n bestMatch == null ||\n diff! < 0 ||\n // Larger priority wins\n (diff === 0 &&\n entry.value.priority > bestMatch.value.priority) ||\n // Last inserted wins\n (diff === 0 &&\n entry.value.priority === bestMatch.value.priority &&\n entry.id > bestMatch.id)\n ) {\n bestMatch = entry;\n }\n }\n return bestMatch?.value.label ?? null;\n },\n startIssuesNavigation: async ({\n validate = true,\n setTouched = validate,\n } = {}) => {\n const formManager = get().controller.getState().formManager;\n if (setTouched) {\n await formManager.setTouched();\n }\n if (validate && formManager.autoValidationStatus === \"inactive\") {\n await formManager.validate();\n }\n get().startIssuesNavigation?.();\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.setState({ controller });\n }, [controller, store]);\n\n return useMemo(\n () => ({\n formTitle,\n disabled,\n readOnly,\n issuesDisplayMode,\n displayIssueCodes,\n formAppElement,\n store,\n }),\n [\n disabled,\n displayIssueCodes,\n formAppElement,\n formTitle,\n issuesDisplayMode,\n readOnly,\n store,\n ],\n );\n}\n\n/** Returns the context of the form app. */\nexport function useFormAppContext<T = unknown>(): FormAppContextValue<T> {\n const formAppContext = useContext(FormAppContext);\n if (!formAppContext) {\n throw new Error(\"Form app context not in scope.\");\n }\n return formAppContext as FormAppContextValue<T>;\n}\n\n/** Returns the title of the form, if provided to the `FormApp` component. */\nexport function useFormTitle(): string | undefined {\n return useFormAppContext().formTitle;\n}\n\n/** Returns a boolean representing whether the form is disabled. */\nexport function useFormIsDisabled(): boolean {\n return useFormAppContext().disabled;\n}\n\n/** Returns a boolean representing whether the form is read-only. */\nexport function useFormIsReadOnly(): boolean {\n return useFormAppContext().readOnly;\n}\n\n/** Returns the form app's display mode for issue messages. */\nexport function useIssuesDisplayMode(): IssuesDisplayMode {\n return useFormAppContext().issuesDisplayMode;\n}\n\n/**\n * Returns whether issue codes should be displayed (by default) within issue\n * messages.\n */\nexport function useDisplayIssueCodesInIssueMessages(): boolean {\n return useFormAppContext().displayIssueCodes;\n}\n\n/** Hook providing access to the form app's HTML form element. */\nexport function useFormAppElement(): HTMLFormElement {\n return useFormAppContext().formAppElement!;\n}\n\n/**\n * Hook exposing a function that can be used to specify the height of the form\n * app's top bar.\n */\nexport function useSetTopBarHeight(): (height?: number) => void {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n return useCallback(\n (height?: number) =>\n !printing && store.setState({ topBarHeight: height ?? 0 }),\n [printing, store],\n );\n}\n\n/**\n * Hook exposing a function that can be used to specify the width of the form\n * app's left panel.\n */\nexport function useSetLeftSidebarWidth(): (width?: number) => void {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n return useCallback(\n (width?: number) =>\n !printing && store.setState({ leftSidebarWidth: width ?? 0 }),\n [printing, store],\n );\n}\n\n/**\n * Hook exposing a function that can be used to specify the height of the form\n * app's bottom panel.\n */\nexport function useSetBottomPanelHeight(): (height?: number) => void {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n return useCallback(\n (height?: number) =>\n !printing && store.setState({ bottomPanelHeight: height ?? 0 }),\n [printing, store],\n );\n}\n\n/**\n * Returns the current issues panel path of the form app and a function that can\n * be used to set it, ala `useState`.\n */\nexport function useIssuesPanelPath(): [\n AbsolutePath | null,\n FormAppActions[\"setIssuesPanelPath\"],\n] {\n return useStore(\n useFormAppContext().store,\n useShallow((state) => [\n state.issuesPanelPath,\n state.actions.setIssuesPanelPath,\n ]),\n );\n}\n\n/** Hook exposing a function that can be used to focus a path within a form app. */\nexport function useFocus(): FormAppActions[\"focus\"] {\n return useStore(useFormAppContext().store, (state) => state.actions.focus);\n}\n\n/** Hook exposing a function that can be used to reset the focus. */\nexport function useResetFocus(): FormAppActions[\"resetFocus\"] {\n return useStore(\n useFormAppContext().store,\n (state) => state.actions.resetFocus,\n );\n}\n\n/**\n * Hook used to register a controller within the form app. This makes the form\n * app aware that a controller of a certain path is currently being rendered.\n */\nexport function useRegisterController(controller: Controller<any>) {\n const store = useFormAppContext().store;\n const path = controller.usePath();\n const printing = usePrinting();\n useEffect(() => {\n if (!printing) {\n return store.getState().actions.registerController(path, controller);\n }\n }, [store, controller, path, printing]);\n}\n\n/** Hook to check whether there is a registered controller for the provided path. */\nexport function useIsRegistered(path?: AbsolutePath | null): boolean {\n return useStore(\n useFormAppContext().store,\n (state) => path != null && state.actions.isRegistered(path),\n );\n}\n\n/** Hook exposing the latest path that the user has interacted with. */\nexport function useLatestInteraction(): AbsolutePath {\n return useStore(\n useFormAppContext().store,\n (state) => state.latestInteraction,\n );\n}\n\n/** Hook exposing a function to set the latest path the user has interacted with. */\nexport function useSetLatestInteraction(): FormAppActions[\"setLatestInteraction\"] {\n return useStore(\n useFormAppContext().store,\n (state) => state.actions.setLatestInteraction,\n );\n}\n\n/** Hook used to register issue messages within the form app. */\nexport function useRegisterIssueMessages(\n path: AbsolutePath | null | undefined,\n issueMessages?: Record<string, IssueMessagesByCode>,\n priority?: number,\n) {\n const store = useFormAppContext().store;\n const printing = usePrinting();\n useEffect(() => {\n if (!printing && path != null) {\n return store\n .getState()\n .actions.registerIssueMessages(path, issueMessages, priority);\n }\n }, [path, issueMessages, priority, store, printing]);\n}\n\n/** Hook used to get the issue message value for the provided path and code. */\nexport function useRegisteredIssueMessage(\n path: AbsolutePath | null | undefined,\n code: string,\n): IssueMessageValue | null {\n return useStore(useFormAppContext().store, (state) =>\n path == null ? null : state.actions.getRegisteredIssueMessage(path, code),\n );\n}\n\n/** Hook used to register a label within the form app. */\nexport function useRegisterLabel(\n path: AbsolutePath | null | undefined,\n label: ReactNode,\n priority = 0,\n) {\n const store = useFormAppContext().store;\n const printing = usePrinting();\n useEffect(() => {\n if (!printing && path != null) {\n return store.getState().actions.registerLabel(path, label, priority);\n }\n }, [store, path, label, priority, printing]);\n}\n\n/**\n * Hook used to get the label parts associated with the active issues panel\n * path.\n */\nexport function useActiveIssuesPanelBreadcrumb(): BreadcrumbItem[] | null {\n return useStore(\n useFormAppContext().store,\n useEqualityFn(\n (state) => state.actions.getActiveIssuesPanelBreadcrumb(),\n equalBreadcrumbItems,\n ),\n );\n}\nfunction equalBreadcrumbItems(\n breadcrumbs1: BreadcrumbItem[] | null,\n breadcrumbs2: BreadcrumbItem[] | null,\n) {\n if (breadcrumbs1 == null || breadcrumbs2 == null) {\n return breadcrumbs1 === breadcrumbs2;\n }\n return (\n breadcrumbs1.length === breadcrumbs2.length &&\n breadcrumbs1.every((breadcrumb1, i) => {\n const breadcrumb2 = breadcrumbs2[i];\n return (\n breadcrumb1.path.toString() === breadcrumb2.path.toString() &&\n Object.is(breadcrumb1.label, breadcrumb2.label)\n );\n })\n );\n}\n\n/**\n * Hook exposing a function that can be used to start navigating through the\n * form app's issues.\n */\nexport function useStartIssuesNavigation(): FormAppActions[\"startIssuesNavigation\"] {\n return useStore(\n useFormAppContext().store,\n (state) => state.actions.startIssuesNavigation,\n );\n}\n\n/** Options available to the {@link useOnPathFocus} hook. */\nexport interface UseOnFocusedPathChangeOptions {\n /**\n * Whether to run the callback immediately with the current focused path.\n *\n * @default true\n */\n fireImmediately?: boolean;\n}\n\n/**\n * Hook used to run a given function whenever the form app's focused path\n * changes.\n *\n * @param cb Function to run when the focused path changes. This function should\n * hopefully not change on every render (i.e., it should be memoised via\n * `useCallback` or be defined externally).\n * @param options Hook options.\n */\nexport function useOnPathFocus(\n cb: (focusedPath: AbsolutePath) => void,\n { fireImmediately = true }: UseOnFocusedPathChangeOptions = {},\n) {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n useEffect(() => {\n if (!printing) {\n return store.subscribe(\n ({ focusedPath, focusCounter }) => ({ focusedPath, focusCounter }),\n ({ focusedPath }) => focusedPath && cb(focusedPath),\n { fireImmediately, equalityFn: shallow },\n );\n }\n }, [cb, fireImmediately, printing, store]);\n}\n\n/** Hook used to set the function which starts issue navigation. */\nexport function useSetStartIssuesNavigation(fn: () => void) {\n const { store } = useFormAppContext();\n const printing = usePrinting();\n useEffect(() => {\n if (!printing) {\n store.setState({ startIssuesNavigation: fn });\n return () => store.setState({ startIssuesNavigation: undefined });\n }\n }, [fn, printing, store]);\n}\n","import type { Controller } from \"@ostack.tech/kform-react\";\nimport { NATIVE_CONTROLS, useCssVars, useSpacing } from \"@ostack.tech/ui\";\nimport { type RefObject, useCallback, useRef } from \"react\";\n\nimport { useOnPathFocus } from \"../components/FormApp\";\nimport { useResetFocus } from \"../components/FormApp/FormAppContext.ts\";\nimport { usePrefix } from \"../providers/PrefixSuffixProvider\";\n\nconst FOCUSABLE_ELEMENTS = [\"INPUT\", \"SELECT\", \"TEXTAREA\"];\n\n/**\n * Function used to scroll an element into view.\n *\n * @param el Element to scroll into view.\n * @param options Scroll into view options.\n */\nexport type ScrollIntoViewFn = (\n el: HTMLElement,\n options?: ScrollIntoViewOptions,\n) => void;\n\n/**\n * Hook used to autofocus a control when the active path changes, given the\n * control's path.\n *\n * @param controller Control's controller.\n * @param enabled Whether to enable the auto-focus behaviour.\n * @returns Reference that should be set on the focusable element of the\n * control.\n */\nexport function useControlAutofocus<\n T = unknown,\n TElem extends HTMLElement = HTMLElement,\n>(\n { usePath, useExists }: Controller<T>,\n enabled = true,\n): RefObject<TElem | null> {\n const controlRef = useRef<TElem | null>(null);\n const path = usePath();\n const exists = useExists();\n const resetFocus = useResetFocus();\n const scrollIntoView = useScrollIntoView();\n\n const timeoutId = useRef<number>(undefined);\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const control = controlRef.current;\n if (enabled && control && exists && path.equals(focusedPath)) {\n clearTimeout(timeoutId.current);\n timeoutId.current = window.setTimeout(() => {\n scrollIntoView(control);\n visiblyFocus(control);\n resetFocus();\n }, 50);\n }\n },\n [enabled, exists, path, resetFocus, scrollIntoView],\n ),\n );\n\n return controlRef;\n}\n\n/**\n * Visibly focuses the provided element.\n *\n * @param el Element to visibly focus.\n * @param options Focus options.\n */\nexport function visiblyFocus(el: HTMLElement, options?: FocusOptions) {\n const focusOptions: FocusOptions = {\n preventScroll: true,\n // This option is experimental, but works well in Firefox, so might as well\n // use it\n focusVisible: true,\n ...options,\n } as any;\n\n if (FOCUSABLE_ELEMENTS.includes(el.tagName)) {\n el.focus(focusOptions);\n } else {\n // XXX: Trick browser into triggering `:focus-visible`\n const contentEditable = el.contentEditable;\n el.contentEditable = \"true\";\n el.focus(focusOptions);\n el.contentEditable = contentEditable;\n }\n}\n\n/**\n * Returns a function used the scroll an element into view, taking into account\n * the form app's sticky elements, so that elements don't end up hidden behind\n * them.\n */\nexport function useScrollIntoView(): ScrollIntoViewFn {\n const prefix = usePrefix();\n const spacing = useSpacing();\n const { cssVar } = useCssVars({ prefix });\n\n return useCallback(\n (el: HTMLElement, options?: ScrollIntoViewOptions) => {\n const scrollableParent = getScrollableParent(el);\n const scrollMarginBlockStart = el.style.scrollMarginBlockStart;\n const scrollMarginBlockEnd = el.style.scrollMarginBlockEnd;\n el.style.scrollMarginBlockStart = `calc(${cssVar(\"top-bar-height\")} + ${cssVar(\n \"form-pages-page-header-height\",\n )} + ${spacing(4)})`;\n el.style.scrollMarginBlockEnd = `calc(${cssVar(\"bottom-panel-height\")} + ${spacing(4)})`;\n const shouldCenter =\n !NATIVE_CONTROLS.has(el.tagName) ||\n scrollableParent !==\n (document.scrollingElement ?? document.documentElement);\n el.scrollIntoView({\n block: shouldCenter ? \"center\" : \"nearest\",\n inline: shouldCenter ? \"center\" : \"nearest\",\n behavior: \"smooth\",\n ...options,\n });\n el.style.scrollMarginBlockStart = scrollMarginBlockStart;\n el.style.scrollMarginBlockEnd = scrollMarginBlockEnd;\n },\n [cssVar, spacing],\n );\n}\n\n/**\n * Gets the nearest scrollable parent.\n *\n * @param el Element for which to get the nearest scrollable parent.\n */\nfunction getScrollableParent(el: Element): Element {\n let current = el.parentNode;\n while (current instanceof Element) {\n const overflow = getComputedStyle(current, null).getPropertyValue(\n \"overflow\",\n );\n if (overflow.includes(\"scroll\") || overflow.includes(\"auto\")) {\n return current;\n }\n current = current.parentNode;\n }\n return document.scrollingElement ?? document.documentElement;\n}\n","import { useFormController } from \"@ostack.tech/kform-react\";\nimport { useCallback } from \"react\";\n\nimport {\n useScrollIntoView,\n visiblyFocus,\n} from \"../../utils/useControlAutofocus.ts\";\nimport {\n useFormAppElement,\n useIssuesDisplayMode,\n useOnPathFocus,\n useResetFocus,\n} from \"./FormAppContext.ts\";\n\n/** Component enabling support for auto-focusing the form app via `focus(\"/\")`. */\nexport function FormAppAutoFocus() {\n const initialized = useFormController().useInitialized();\n const formAppEl = useFormAppElement();\n const scrollIntoView = useScrollIntoView();\n\n const issuesDisplayMode = useIssuesDisplayMode();\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n if (initialized && focusedPath.isRoot) {\n // In inline mode an issues popover should get focused instead\n if (issuesDisplayMode === \"panel\") {\n scrollIntoView(formAppEl);\n visiblyFocus(formAppEl);\n }\n resetFocus();\n }\n },\n [initialized, issuesDisplayMode, resetFocus, scrollIntoView, formAppEl],\n ),\n );\n return null;\n}\n","import {\n cx,\n useCombinedRef,\n useCssVars,\n useResponsiveValues,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type Dispatch,\n forwardRef,\n type SetStateAction,\n useEffect,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport type { FormAppProps } from \"./FormApp.tsx\";\nimport { useFormAppContext } from \"./FormAppContext.ts\";\n\n/** Properties of the form application element component. */\nexport interface FormAppElementProps\n extends\n Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"onReset\">,\n Pick<FormAppProps, \"minHeight\"> {\n formAppElement: HTMLFormElement | null;\n setFormAppElement: Dispatch<SetStateAction<HTMLFormElement | null>>;\n}\n\n/** Form application element. */\nexport const FormAppElement = forwardRef<\n ComponentRef<\"form\">,\n FormAppElementProps\n>(function FormAppElement(\n {\n formAppElement,\n setFormAppElement,\n minHeight,\n className,\n style,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { cssVarName } = useCssVars({ prefix });\n const { responsiveValueToCssVarsAndDataAttrs } = useResponsiveValues({\n prefix,\n });\n const { store } = useFormAppContext();\n\n // Top-bar height\n useEffect(\n () =>\n store.subscribe(\n (state) => state.topBarHeight,\n (height) =>\n formAppElement?.style.setProperty(\n cssVarName(\"top-bar-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, formAppElement, store],\n );\n\n // Left sidebar width\n useEffect(\n () =>\n store.subscribe(\n (state) => state.leftSidebarWidth,\n (width) =>\n formAppElement?.style.setProperty(\n cssVarName(\"left-sidebar-width\"),\n `${width}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, formAppElement, store],\n );\n\n // Bottom panel height\n useEffect(\n () =>\n store.subscribe(\n (state) => state.bottomPanelHeight,\n (height) =>\n formAppElement?.style.setProperty(\n cssVarName(\"bottom-panel-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, formAppElement, store],\n );\n\n // Form app min height\n const { cssVars, dataAttrs } = responsiveValueToCssVarsAndDataAttrs(\n \"form-app\",\n \"min-height\",\n minHeight,\n (v) => (typeof v === \"number\" ? `${v}px` : v),\n );\n\n const combinedFormAppRef = useCombinedRef(setFormAppElement, forwardedRef);\n return (\n <form\n className={cx(prefix(\"form-app\"), className)}\n style={{ ...cssVars, ...style }}\n tabIndex={0}\n {...dataAttrs}\n {...otherProps}\n ref={combinedFormAppRef}\n >\n {children}\n </form>\n );\n});\n","import type { Path } from \"@ostack.tech/kform\";\nimport { useResolvedPath } from \"@ostack.tech/kform-react\";\nimport type { ReactNode } from \"react\";\n\nimport type { IssueMessagesByCode } from \"../IssueMessages\";\nimport { useRegisterIssueMessages } from \"./FormAppContext.ts\";\n\n/** Properties of the form app issue messages component. */\nexport interface FormAppIssueMessagesProps {\n /** Base path for the paths used in `messages`. */\n path?: string | Path;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their code).\n *\n * Provided paths may contain wildcards, which will have a lower priority when\n * matched against.\n *\n * These messages are used by the `IssueMessages` and `IssuesPanel`\n * components.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"/**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"/my/field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /**\n * Priority to use when registering issue messages.\n *\n * When multiple issue messages are associated with the same path, then the\n * one registered with the highest priority \"wins\".\n *\n * @default 0\n */\n priority?: number;\n children: ReactNode;\n}\n\n/** Component used to register new issue messages within the form app. */\nexport function FormAppIssueMessages({\n path,\n issueMessages,\n priority,\n children,\n}: FormAppIssueMessagesProps) {\n const absolutePath = useResolvedPath(path);\n useRegisterIssueMessages(absolutePath, issueMessages, priority);\n return children;\n}\n","import {\n AbsolutePath,\n type Path,\n type Schema,\n type SchemaKt,\n} from \"@ostack.tech/kform\";\nimport {\n type Controller,\n FormContext,\n type FormOptions,\n useForm,\n} from \"@ostack.tech/kform-react\";\nimport {\n PrefixProvider,\n type Responsive,\n Root,\n useIsInRoot,\n usePrintInProgress,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport {\n ActivePathProvider,\n type OnActivePathChangeNavigationOptions,\n} from \"../../providers/ActivePathProvider\";\nimport type { LocalizationObject } from \"../../providers/LocalizationProvider\";\nimport {\n LocalizationContext,\n LocalizationProvider,\n} from \"../../providers/LocalizationProvider\";\nimport { PrefixSuffixProvider } from \"../../providers/PrefixSuffixProvider\";\nimport type { IssueMessagesByCode } from \"../IssueMessages\";\nimport { FormAppAutoFocus } from \"./FormAppAutoFocus.tsx\";\nimport { FormAppContext, useCreateFormAppContext } from \"./FormAppContext.ts\";\nimport { FormAppElement } from \"./FormAppElement.tsx\";\nimport { FormAppIssueMessages } from \"./FormAppIssueMessages.tsx\";\n\n/** Mode of displaying issue messages. */\nexport type IssuesDisplayMode = \"inline\" | \"panel\";\n\n/** Properties of the form app component. */\nexport type FormAppProps<T = any> = Pick<\n ComponentPropsWithoutRef<typeof Root>,\n | \"enableErrorReporting\"\n | \"reportError\"\n | \"errorReportingUrl\"\n | \"errorReportingMethod\"\n | \"encodeErrorReport\"\n | \"encodedErrorReportMimeType\"\n | \"errorReportingOptions\"\n | \"baseDocumentTitle\"\n | \"documentTitleBaseSeparator\"\n | \"documentTitleBreadcrumbsSeparator\"\n | \"portalsContainer\"\n | \"tooltipsDelayDuration\"\n | \"tooltipsSkipDelayDuration\"\n | \"disableTooltipsHoverableContent\"\n | \"toastsLabel\"\n | \"toastsDuration\"\n | \"toastsSwipeDirection\"\n | \"toastsSwipeThreshold\"\n | \"toastViewportHotkey\"\n | \"toastViewportLabel\"\n | \"toastViewportProps\"\n | \"errorBoundaryProps\"\n> &\n FormOptions<T> &\n Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"onReset\"> & {\n /** Schema of the form. */\n schema: Schema<T> | SchemaKt;\n /** Title of the form. */\n formTitle?: string;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * the form app. Defaults to the `formTitle`.\n */\n issuesPanelLabel?: ReactNode;\n /** Whether to disable the whole form. */\n disabled?: boolean;\n /** Whether to set the whole form as read-only. */\n readOnly?: boolean;\n /**\n * Custom suffix to add to the ostack/UI's prefix when prefixing all\n * component classes, styles, _etc._\n *\n * This prefix-suffix should match the `$prefix-suffix` SCSS variable.\n */\n prefixSuffix?: string;\n /** Uncontrolled form app locale. */\n defaultLocale?: LocalizationObject;\n /** Controlled form app locale. */\n locale?: LocalizationObject;\n /**\n * Function called when the locale changes.\n *\n * @param locale New locale.\n */\n onLocaleChange?: (locale: LocalizationObject) => void;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their\n * code).\n *\n * Provided paths may contain wildcards, which will have a lower priority\n * when matched against.\n *\n * These messages are used by the `IssueMessages` component.\n *\n * **Note:** Changes to `issueMessages` are handled correctly, but are not\n * efficient. Please make sure that the identity of the provided value\n * doesn't change at every render.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"/**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"/my/field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /**\n * Mode of displaying issues:\n *\n * - `inline` mode dispays issue messages near the component containing the\n * issues. In this mode the bottom issues panel only functions as an aid\n * for navigating issues.\n * - `panel` mode displays issue messages within the bottom issues panel.\n *\n * @default inline\n */\n issuesDisplayMode?: IssuesDisplayMode;\n /**\n * Global setting which specifies whether issue codes should be added to\n * each issue message.\n *\n * @default false\n */\n displayIssueCodes?: boolean;\n /**\n * When provided, the form app's active path will be controlled by a URL\n * search parameter with the provided name.\n */\n activePathSearchParam?: string;\n /** Uncontrolled default active path to use. */\n defaultActivePath?: string | Path;\n /** Controlled active path to use. */\n activePath?: string | Path;\n /**\n * Callback called whenever the active path changes.\n *\n * @param activePath New active path.\n * @param options Navigation options to use when controlling the active path\n * via the browser's URL.\n */\n onActivePathChange?: (\n activePath: AbsolutePath,\n options: OnActivePathChangeNavigationOptions,\n ) => void;\n /**\n * Function called when a form path is focused.\n *\n * @param path Focused path.\n */\n onPathFocus?: (path: AbsolutePath) => void;\n /**\n * Minimum height of the form app. Values should **not** be percentages.\n *\n * @default \"100dvh\"\n */\n minHeight?: Responsive<number | string>;\n /** Reference to the form app's API. */\n apiRef?: Ref<FormAppApi<T> | undefined>;\n };\n\n/** Imperative form app API. */\nexport type FormAppApi<T = unknown> = Controller<T> & {\n /**\n * Focuses the form element at the provided path.\n *\n * @param path Path of element to focus.\n */\n focus: (path: string | Path) => void;\n /**\n * Starts issues navigation (when an `IssuesPanel` component exists within).\n *\n * @param options Options used when starting issues validation.\n */\n startIssuesNavigation: (options: {\n validate?: boolean;\n setTouched?: boolean;\n }) => PromiseLike<void>;\n};\n\n/**\n * Root component of a form application.\n *\n * This component automatically renders the ostack/UI's `Root` component when\n * not rendered inside of one, in which case it accepts properties that would\n * otherwise be passed to the ostack/UI `Root` component. In this scenario, the\n * ostack/UI's `locale` is automatically provided to the ostack/UI `Root`\n * component from the provided `FormApp` `locale`.\n */\nexport const FormApp = forwardRef(function FormApp<T = unknown>(\n {\n enableErrorReporting,\n reportError,\n errorReportingUrl,\n errorReportingMethod,\n encodeErrorReport,\n encodedErrorReportMimeType,\n errorReportingOptions,\n baseDocumentTitle,\n documentTitleBaseSeparator,\n documentTitleBreadcrumbsSeparator,\n portalsContainer,\n tooltipsDelayDuration,\n tooltipsSkipDelayDuration,\n disableTooltipsHoverableContent,\n toastsLabel,\n toastsDuration,\n toastsSwipeDirection,\n toastsSwipeThreshold,\n toastViewportHotkey,\n toastViewportLabel,\n toastViewportProps,\n errorBoundaryProps,\n schema,\n initialValue,\n formTitle,\n issuesPanelLabel,\n disabled = false,\n readOnly = false,\n prefix: newPrefix,\n prefixSuffix,\n defaultLocale,\n locale: controlledLocale,\n onLocaleChange,\n issueMessages,\n issuesDisplayMode = \"inline\",\n displayIssueCodes = false,\n // activePathSearchParam,\n defaultActivePath,\n activePath,\n onActivePathChange,\n onPathFocus,\n minHeight,\n apiRef,\n externalContexts,\n validationMode = readOnly ? \"manual\" : \"auto\",\n confirmUnloadWhenDirty,\n confirmUnloadMessage,\n onSubmit,\n onInvalidSubmit,\n onSuccessfulSubmit,\n onFailedSubmit,\n validateOnSubmit,\n setTouchedOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n onReset,\n onInitialized,\n onUninitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n ...otherProps\n }: FormAppProps,\n forwardedRef: ForwardedRef<ComponentRef<\"form\">>,\n) {\n const isInRoot = useIsInRoot();\n const rootProps = {\n enableErrorReporting,\n reportError,\n errorReportingUrl,\n errorReportingMethod,\n encodeErrorReport,\n encodedErrorReportMimeType,\n errorReportingOptions,\n baseDocumentTitle,\n documentTitleBaseSeparator,\n documentTitleBreadcrumbsSeparator,\n portalsContainer,\n tooltipsDelayDuration,\n tooltipsSkipDelayDuration,\n disableTooltipsHoverableContent,\n toastsLabel,\n toastsDuration,\n toastsSwipeDirection,\n toastsSwipeThreshold,\n toastViewportHotkey,\n toastViewportLabel,\n toastViewportProps,\n errorBoundaryProps,\n };\n if (isInRoot && Object.values(rootProps).some((prop) => prop !== undefined)) {\n warnOnce(\n `FormApp: Properties ${Object.keys(rootProps)\n .map((prop) => `\\`${prop}\\``)\n .join(\", \")} have no effect when the \\`FormApp\\` is already ` +\n \"inside an ostack/UI's `Root` component. Please set any of these \" +\n \"properties on the `Root` component directly instead.\",\n );\n }\n\n const contextLocale = useContext(LocalizationContext)?.locale;\n const locale = controlledLocale ?? defaultLocale ?? contextLocale;\n if (locale == null) {\n throw new Error(\n \"FormApp: No locale has been provided. Either provide a \" +\n \"`defaultLocale`/`locale` property or wrap the component in a \" +\n \"`LocalizationProvider`.\",\n );\n }\n formTitle ??= locale.FormApp.formTitle;\n issuesPanelLabel ??= locale.FormApp.issuesPanelLabel ?? formTitle;\n confirmUnloadMessage ??= locale.FormApp.confirmUnloadMessage;\n\n const controller = useForm<T>(schema, {\n initialValue,\n externalContexts,\n validationMode,\n confirmUnloadWhenDirty,\n confirmUnloadMessage,\n onSubmit,\n onInvalidSubmit,\n onSuccessfulSubmit,\n onFailedSubmit,\n validateOnSubmit,\n setTouchedOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n onReset,\n onInitialized,\n onUninitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n } as FormOptions<T>);\n const { formProps } = controller;\n\n // Reference to the form app element (used to scroll into view on page\n // changes, since scrolling a page itself into view hides elements under the\n // top-bar)\n const [formAppElement, setFormAppElement] = useState<HTMLFormElement | null>(\n null,\n );\n\n const formManager = controller.useFormManager();\n const formContext = useMemo(\n () => ({\n formManager,\n currentPath: AbsolutePath.ROOT,\n controller,\n }),\n [controller, formManager],\n );\n\n const printInProgress = usePrintInProgress();\n const displayDisabled =\n controller.useSubmitting() || disabled || printInProgress;\n const formAppContextValue = useCreateFormAppContext<T>({\n formTitle,\n disabled: displayDisabled,\n readOnly,\n issuesDisplayMode,\n displayIssueCodes,\n controller,\n onPathFocus,\n formAppElement,\n });\n const { store } = formAppContextValue;\n\n useEffect(\n () =>\n store\n .getState()\n .actions.registerController(AbsolutePath.ROOT, controller),\n [controller, store],\n );\n\n const absolutePath = controller.usePath();\n useEffect(\n () =>\n store.getState().actions.registerLabel(absolutePath, issuesPanelLabel),\n [absolutePath, issuesPanelLabel, store],\n );\n\n // Expose the control's API via `apiRef`\n const { focus, startIssuesNavigation } = useStore(\n store,\n (state) => state.actions,\n );\n useImperativeHandle(\n apiRef,\n () => ({\n ...controller,\n focus,\n startIssuesNavigation,\n }),\n [focus, controller, startIssuesNavigation],\n );\n\n const formAppEl = (\n <FormAppElement\n minHeight={minHeight}\n formAppElement={formAppElement}\n setFormAppElement={setFormAppElement}\n {...formProps}\n {...otherProps}\n ref={forwardedRef}\n />\n );\n\n return (\n <PrefixProvider prefix={newPrefix}>\n <PrefixSuffixProvider prefixSuffix={prefixSuffix}>\n <LocalizationProvider\n defaultLocale={defaultLocale}\n locale={controlledLocale}\n onLocaleChange={onLocaleChange}\n >\n <FormContext.Provider value={formContext}>\n <FormAppContext.Provider value={formAppContextValue as never}>\n <ActivePathProvider\n defaultActivePath={defaultActivePath}\n activePath={activePath}\n onActivePathChange={onActivePathChange}\n >\n <FormAppIssueMessages\n issueMessages={locale.FormApp.issueMessages}\n priority={-1}\n >\n <FormAppIssueMessages issueMessages={issueMessages}>\n <FormAppAutoFocus />\n\n {isInRoot ? (\n formAppEl\n ) : (\n <Root asChild {...rootProps}>\n {formAppEl}\n </Root>\n )}\n </FormAppIssueMessages>\n </FormAppIssueMessages>\n </ActivePathProvider>\n </FormAppContext.Provider>\n </FormContext.Provider>\n </LocalizationProvider>\n </PrefixSuffixProvider>\n </PrefixProvider>\n );\n});\n","import { type ReactNode, useMemo } from \"react\";\n\nimport { FormAppContext, useFormAppContext } from \"./FormAppContext.ts\";\n\n/** Properties of the form app status component. */\nexport interface FormAppStatusProps {\n /**\n * Whether to mark the form app as disabled for children of this component.\n *\n * This property has no effect when set to `false`.\n *\n * @default false\n */\n disabled?: boolean;\n /**\n * Whether to mark the form app as read-only for children of this component.\n *\n * This property has no effect when set to `false`.\n *\n * @default false\n */\n readOnly?: boolean;\n children: ReactNode;\n}\n\n/** Component used to apply a different form app status to part of the form. */\nexport function FormAppStatus({\n disabled = false,\n readOnly = false,\n children,\n}: FormAppStatusProps) {\n const formAppContext = useFormAppContext();\n return (\n <FormAppContext.Provider\n value={useMemo(\n () => ({\n ...formAppContext,\n disabled: formAppContext.disabled || disabled,\n readOnly: formAppContext.readOnly || readOnly,\n }),\n [disabled, formAppContext, readOnly],\n )}\n >\n {children}\n </FormAppContext.Provider>\n );\n}\n","import { AbsolutePath, AbsolutePathFragment } from \"@ostack.tech/kform\";\n\n/**\n * Function which selects the most \"specific\" path from a list of paths, given a\n * path to match. `currentActivePath` contains the path that is currently\n * active.\n *\n * The list of paths may contain paths with a single trailing wildcard.\n *\n * This function is used by the `Annexes`, `FormPages`, and `FormStepper`\n * components to select the next path that should be focused when the focused\n * path changes.\n */\nexport function mostSpecificPath(\n toMatch: AbsolutePath | null,\n paths: AbsolutePath[],\n currentActivePath: AbsolutePath | null,\n): AbsolutePath | null {\n if (!toMatch || paths.length === 0) {\n return null;\n }\n\n // Filter paths containing the focused path and pick the one with the most\n // specific (longest) path\n const mostSpecific = paths\n .filter((path) =>\n path.append(AbsolutePathFragment.RecursiveWildcard).contains(toMatch),\n )\n .reduce(\n (mostSpecific: AbsolutePath | null, path) =>\n mostSpecific === null || path.size > mostSpecific.size\n ? // Replace wildcard with the id of the path to match\n path.lastFragment === AbsolutePathFragment.Wildcard\n ? new AbsolutePath(toMatch.fragments.slice(0, path.size))\n : path\n : mostSpecific,\n null,\n );\n if (mostSpecific) {\n return mostSpecific;\n }\n\n // Return the currently active path when it is still one of the provided paths\n if (\n currentActivePath &&\n paths.some((path) => path.contains(currentActivePath))\n ) {\n return currentActivePath;\n }\n\n // Fallback to the first path\n return paths[0];\n}\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n type DisplayStatus,\n type FormManager,\n listableSize,\n type Path,\n type Schema,\n type SealedValidationIssue,\n sliceTable,\n type Table,\n type TableRowId,\n} from \"@ostack.tech/kform\";\nimport {\n computed,\n useConstant,\n useLatestValues,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { useActivePathContext } from \"../../providers/ActivePathProvider\";\nimport { mostSpecificPath } from \"../../utils/mostSpecificPath.ts\";\nimport { useOnPathFocus } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport type { AnnexesProps, AnnexObject } from \"./Annexes.tsx\";\n\n/** Value of the annexes' context. */\nexport type AnnexesContextValue = AnnexesStore;\n\n/** Resolved annex object. */\nexport interface ResolvedAnnexObject extends AnnexObject {\n path: AbsolutePath;\n}\n\n/** Annex state. */\nexport interface AnnexState {\n path: AbsolutePath;\n title: ReactNode;\n subtitle?: ReactNode;\n description?: ReactNode;\n documentTitle?: string | null;\n isRepetitive: boolean;\n schema: Schema;\n isNull: boolean;\n dirty: boolean | undefined;\n deferredDisplayStatus: DisplayStatus | undefined;\n deferredIssuesToDisplay: SealedValidationIssue[];\n}\n\n/** Repetitive annex state. */\nexport type RepetitiveAnnexState = Pick<\n ResolvedAnnexObject,\n \"path\" | \"maxAnnexes\"\n> & {\n rowIds?: TableRowId[];\n schema: Schema;\n deferredIssuesToDisplay: SealedValidationIssue[];\n};\n\n/** State of the annexes. */\nexport interface AnnexesState {\n annexes: ResolvedAnnexObject[];\n activeAnnex: AbsolutePath | null;\n nextActiveAnnex: AbsolutePath | null;\n activeAnnexIndex: () => number;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new object\n // instances\n annexStates: [Record<string, AnnexState | null>];\n repetitiveAnnexStates: [Record<string, RepetitiveAnnexState | null>];\n tabStates: () => AnnexState[];\n tablessStates: () => (AnnexState | RepetitiveAnnexState)[];\n waitingRegistration: () => AbsolutePath[];\n actions: AnnexesActions;\n}\n\n/** Actions of the annexes. */\nexport interface AnnexesActions {\n getAnnexState: (path: AbsolutePath) => AnnexState | null;\n getRepetitiveAnnexState: (path: AbsolutePath) => RepetitiveAnnexState | null;\n setAnnexes: (annexes: ResolvedAnnexObject[]) => void;\n buildAnnexStates: (\n annexes?: ResolvedAnnexObject[],\n ) => Record<string, AnnexState | null>;\n buildRepetitiveAnnexStates: (\n annexes?: ResolvedAnnexObject[],\n ) => Record<string, RepetitiveAnnexState | null>;\n setActiveAnnex: (activeAnnex: string | Path | null) => void;\n updateActiveAnnex: (oldActiveAnnexIndex: number) => void;\n registerAnnexState: (path: AbsolutePath, state: AnnexState) => void;\n registerRepetitiveAnnexState: (\n path: AbsolutePath,\n state: RepetitiveAnnexState,\n ) => void;\n addAnnex: (path: AbsolutePath, toAdd: unknown) => Promise<void>;\n removeAnnex: (path: AbsolutePath, isRepetitive: boolean) => Promise<void>;\n}\n\n/** Annexes' store. */\nexport type AnnexesStore = ReturnType<typeof useCreateAnnexesContext>;\n\n/** Annexes' context. */\nexport const AnnexesContext = createContext<AnnexesContextValue | null>(null);\n\n/** Options used to create the annexes' context. */\nexport interface UseCreateAnnexesContextOptions extends Pick<\n AnnexesProps,\n | \"defaultActiveAnnex\"\n | \"activeAnnex\"\n | \"onActiveAnnexChange\"\n | \"onAnnexAdd\"\n | \"onAnnexRemove\"\n> {\n formManager: FormManager;\n basePath: AbsolutePath;\n resolvedAnnexes: ResolvedAnnexObject[];\n}\n\n/** Hook used to create the annexes' context. */\nexport function useCreateAnnexesContext({\n formManager,\n basePath,\n resolvedAnnexes,\n defaultActiveAnnex,\n activeAnnex,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n}: UseCreateAnnexesContextOptions) {\n const setLatestInteraction = useSetLatestInteraction();\n const { activePath, onActivePathChange } = useActivePathContext();\n activeAnnex ??= activePath;\n const latest = useLatestValues({\n printing: usePrinting(),\n formManager,\n onActivePathChange,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n });\n\n const store = useConstant(() =>\n createStore<AnnexesState>()(\n subscribeWithSelector((set, get) => ({\n annexes: resolvedAnnexes,\n activeAnnex:\n activeAnnex === undefined\n ? defaultActiveAnnex == null\n ? null\n : basePath.resolve(defaultActiveAnnex)\n : activeAnnex === null\n ? null\n : basePath.resolve(activeAnnex),\n nextActiveAnnex: null,\n activeAnnexIndex: computed(\n () => [get().activeAnnex, get().tabStates()],\n (activeAnnex, tabStates) =>\n activeAnnex === null\n ? -1\n : tabStates.findIndex((state) => state.path.equals(activeAnnex)),\n ),\n annexStates: [{}],\n repetitiveAnnexStates: [{}],\n tabStates: computed(\n () => [get().annexes, get().annexStates, get().repetitiveAnnexStates],\n (annexes, [annexStates], [repetitiveAnnexStates]) => {\n const tabStates: AnnexState[] = [];\n const pushAnnexState = (path: AbsolutePath) => {\n const state = annexStates[path.toString()];\n if (state != null && !state.isNull) {\n tabStates.push(state);\n }\n };\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const parentPath = annex.path.parent();\n const state = repetitiveAnnexStates[parentPath.toString()];\n if (state?.rowIds) {\n for (const rowId of state.rowIds) {\n pushAnnexState(\n parentPath.append(new AbsolutePathFragment.Id(rowId)),\n );\n }\n }\n } else {\n pushAnnexState(annex.path);\n }\n }\n return tabStates;\n },\n ),\n tablessStates: computed(\n () => [get().annexes, get().annexStates, get().repetitiveAnnexStates],\n (annexes, [annexStates], [repetitiveAnnexStates]) => {\n const tablessStates: (AnnexState | RepetitiveAnnexState)[] = [];\n for (const annex of annexes) {\n let tablessState: AnnexState | RepetitiveAnnexState | null = null;\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n tablessState =\n repetitiveAnnexStates[annex.path.parent().toString()];\n } else {\n const state = annexStates[annex.path.toString()];\n if (state?.isNull) {\n tablessState = state;\n }\n }\n if (tablessState) {\n tablessStates.push(tablessState);\n }\n }\n return tablessStates;\n },\n ),\n waitingRegistration: computed(\n () => [get().annexes, get().annexStates, get().repetitiveAnnexStates],\n (annexes, [annexStates], [repetitiveAnnexStates]) => {\n const waitingRegistration: AbsolutePath[] = [];\n const pushWaitingRegistration = (path: AbsolutePath) => {\n const state = annexStates[path.toString()];\n if (state == null) {\n waitingRegistration.push(path);\n }\n };\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const parentPath = annex.path.parent();\n const state = repetitiveAnnexStates[parentPath.toString()];\n if (!state?.rowIds) {\n waitingRegistration.push(annex.path);\n } else {\n for (const rowId of state.rowIds) {\n pushWaitingRegistration(\n parentPath.append(new AbsolutePathFragment.Id(rowId)),\n );\n }\n }\n } else {\n pushWaitingRegistration(annex.path);\n }\n }\n return waitingRegistration;\n },\n ),\n actions: {\n getAnnexState: (path) =>\n get().annexStates[0][path.toString()] ?? null,\n getRepetitiveAnnexState: (path) =>\n get().repetitiveAnnexStates[0][path.toString()] ?? null,\n setAnnexes: (annexes: ResolvedAnnexObject[]) => {\n const oldActiveAnnexIndex = get().activeAnnexIndex();\n set({\n annexes,\n annexStates: [get().actions.buildAnnexStates(annexes)],\n repetitiveAnnexStates: [\n get().actions.buildRepetitiveAnnexStates(annexes),\n ],\n });\n get().actions.updateActiveAnnex(oldActiveAnnexIndex);\n },\n buildAnnexStates: (\n annexes: ResolvedAnnexObject[] = get().annexes,\n ) => {\n const { getAnnexState, getRepetitiveAnnexState } = get().actions;\n const newAnnexStates: Record<string, AnnexState | null> = {};\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const tablePath = annex.path.parent();\n for (const rowId of getRepetitiveAnnexState(tablePath)\n ?.rowIds ?? []) {\n const rowPath = tablePath.append(\n new AbsolutePathFragment.Id(rowId),\n );\n newAnnexStates[rowPath.toString()] = getAnnexState(rowPath);\n }\n } else {\n newAnnexStates[annex.path.toString()] = getAnnexState(\n annex.path,\n );\n }\n }\n return newAnnexStates;\n },\n buildRepetitiveAnnexStates: (\n annexes: ResolvedAnnexObject[] = get().annexes,\n ) => {\n const { getRepetitiveAnnexState } = get().actions;\n const newRepetitiveAnnexStates: Record<\n string,\n RepetitiveAnnexState | null\n > = {};\n\n for (const annex of annexes) {\n if (annex.path.lastFragment === AbsolutePathFragment.Wildcard) {\n const tablePath = annex.path.parent();\n newRepetitiveAnnexStates[tablePath.toString()] =\n getRepetitiveAnnexState(tablePath);\n }\n }\n return newRepetitiveAnnexStates;\n },\n setActiveAnnex: (path: string | Path | null) => {\n if (latest.printing) {\n return;\n }\n\n const newActiveAnnex =\n path === null || path instanceof AbsolutePath\n ? path\n : new AbsolutePath(path);\n const oldActiveAnnex = get().activeAnnex;\n if (!oldActiveAnnex?.equals(newActiveAnnex)) {\n startTransition(() => {\n set({ activeAnnex: newActiveAnnex });\n if (newActiveAnnex != null) {\n setLatestInteraction(newActiveAnnex);\n }\n latest.onActivePathChange(newActiveAnnex);\n latest.onActiveAnnexChange?.(newActiveAnnex);\n });\n }\n },\n updateActiveAnnex: (oldActiveAnnexIndex: number) => {\n if (latest.printing) {\n return;\n }\n\n const tabStates = get().tabStates();\n const nextActiveAnnex = get().nextActiveAnnex;\n if (\n nextActiveAnnex !== null &&\n tabStates.some((state) => state.path.equals(nextActiveAnnex))\n ) {\n set({ nextActiveAnnex: null });\n get().actions.setActiveAnnex(nextActiveAnnex);\n return;\n }\n\n if (\n get().activeAnnex !== null &&\n (tabStates.some((state) =>\n state.path.equals(get().activeAnnex),\n ) ||\n get()\n .waitingRegistration()\n .some((path) => path.contains(get().activeAnnex!)))\n ) {\n return;\n }\n\n get().actions.setActiveAnnex(\n tabStates[\n Math.max(0, Math.min(oldActiveAnnexIndex, tabStates.length - 1))\n ]?.path ?? null,\n );\n },\n registerAnnexState: (path, state) => {\n const oldActiveAnnexIndex = get().activeAnnexIndex();\n const annexStates = get().annexStates[0];\n annexStates[path.toString()] = state;\n set({ annexStates: [annexStates] });\n get().actions.updateActiveAnnex(oldActiveAnnexIndex);\n },\n registerRepetitiveAnnexState: (path, state) => {\n const oldActiveAnnexIndex = get().activeAnnexIndex();\n const repetitiveAnnexStates = get().repetitiveAnnexStates[0];\n repetitiveAnnexStates[path.toString()] = state;\n set({\n annexStates: [get().actions.buildAnnexStates()],\n repetitiveAnnexStates: [repetitiveAnnexStates],\n });\n get().actions.updateActiveAnnex(oldActiveAnnexIndex);\n },\n addAnnex: async (path, toAdd) => {\n const isRepetitive =\n path.lastFragment === AbsolutePathFragment.Wildcard;\n const setPromise = latest.formManager.set(\n isRepetitive\n ? path.parent().append(AbsolutePathFragment.CollectionEnd)\n : path,\n toAdd,\n );\n\n let addedPath: AbsolutePath;\n if (isRepetitive) {\n addedPath = await latest.formManager.get(\n path.parent(),\n (value: Table) =>\n path\n .parent()\n .append(\n new AbsolutePathFragment.Id(\n sliceTable(value, listableSize(value) - 1)[0][0],\n ),\n ),\n );\n } else {\n addedPath = path;\n }\n set({ nextActiveAnnex: addedPath });\n await setPromise;\n latest.onAnnexAdd?.(addedPath);\n },\n removeAnnex: async (path, isRepetitive) => {\n if (isRepetitive) {\n await latest.formManager.remove(path);\n } else {\n await latest.formManager.set(path, null);\n }\n latest.onAnnexRemove?.(path);\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.getState().actions.setAnnexes(resolvedAnnexes);\n if (activeAnnex !== undefined) {\n const {\n activeAnnex: oldActiveAnnex,\n tabStates,\n waitingRegistration,\n } = store.getState();\n const newActiveAnnex =\n mostSpecificPath(\n activeAnnex === null ? null : basePath.resolve(activeAnnex),\n [...tabStates().map((tab) => tab.path), ...waitingRegistration()],\n oldActiveAnnex,\n ) ?? null;\n store.getState().actions.setActiveAnnex(newActiveAnnex);\n }\n }, [resolvedAnnexes, activeAnnex, basePath, store]);\n\n // Set (possibly new) active annex when focused path changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const { activeAnnex, tabStates, waitingRegistration, actions } =\n store.getState();\n actions.setActiveAnnex(\n mostSpecificPath(\n focusedPath,\n [...tabStates().map((tab) => tab.path), ...waitingRegistration()],\n activeAnnex,\n ) ?? null,\n );\n },\n [store],\n ),\n );\n\n return store;\n}\n\n/** Returns the annexes' context. */\nexport function useAnnexesContext(): AnnexesContextValue {\n const annexesContext = useContext(AnnexesContext);\n if (!annexesContext) {\n throw new Error(\"Annexes context not in scope.\");\n }\n return annexesContext;\n}\n\nexport function useAnnexState<T>(\n path: AbsolutePath,\n selector: (state: AnnexState | null) => T,\n): T {\n return useStore(useAnnexesContext(), (state) =>\n selector(state.actions.getAnnexState(path)),\n );\n}\n","import {\n CurrentPath,\n useCurrentPath,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport {\n cx,\n DocumentTitle,\n ErrorBoundary,\n Spinner,\n TabContent,\n usePrinting,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n Suspense,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormAppIssueMessages, FormAppStatus } from \"../FormApp\";\nimport type { IssueMessagesByCode } from \"../IssueMessages\";\nimport type { AnnexObject } from \"./Annexes.tsx\";\nimport { useAnnexesContext, useAnnexState } from \"./AnnexesContext.ts\";\n\n/** Properties of the annex component. */\nexport interface AnnexProps\n extends\n AnnexObject,\n Omit<\n ComponentPropsWithoutRef<typeof TabContent>,\n \"value\" | \"title\" | \"children\"\n > {\n /** Sets the annex as disabled. */\n disabled?: boolean;\n /** Sets the annex as read-only. */\n readOnly?: boolean;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their code).\n *\n * Provided paths are relative to the annex's path and may contain wildcards,\n * which will have a lower priority when matched against.\n *\n * These messages are used by the `IssueMessages` component.\n *\n * **Note:** Changes to `issueMessages` are handled correctly, but are not\n * efficient. Please make sure that the identity of the provided value doesn't\n * change at every render.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /** Properties to pass to the container element. */\n containerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the `ErrorBoundary` component. */\n errorBoundaryProps?: ComponentPropsWithRef<typeof ErrorBoundary>;\n children?: ReactNode;\n}\n\n/** Component containing the content of an annex. */\nexport const Annex = forwardRef<ComponentRef<typeof TabContent>, AnnexProps>(\n function Annex(\n {\n path,\n // `AnnexObject` props\n title: _title,\n subtitle: _subtitle,\n description: _description,\n issuesPanelLabel: _issuesPanelLabel,\n itemTitle: _itemTitle,\n itemIssuesPanelLabel: _itemIssuesPanelLabel,\n documentTitle: _documentTitle,\n maxAnnexes: _maxAnnexes,\n getValue: _getValue,\n ...otherProps\n },\n forwardedRef,\n ) {\n const annexPath = useResolvedPath(path);\n const store = useAnnexesContext();\n const activeAnnex = useStore(store, (state) => state.activeAnnex);\n const tabStates = useStore(\n store,\n useShallow((state) =>\n state.tabStates().filter((state) => annexPath.contains(state.path)),\n ),\n );\n\n return tabStates.map((state) => {\n const pathStr = state.path.toString();\n return (\n <CurrentPath key={pathStr} path={state.path}>\n <AnnexTabContent\n {...otherProps}\n ref={state.path.equals(activeAnnex) ? forwardedRef : undefined}\n />\n </CurrentPath>\n );\n });\n },\n);\n\ninterface AnnexTabContentProps extends Omit<AnnexProps, keyof AnnexObject> {}\n\nconst AnnexTabContent = forwardRef<\n ComponentRef<typeof TabContent>,\n AnnexTabContentProps\n>(function AnnexTabContent(\n {\n disabled = false,\n readOnly = false,\n issueMessages,\n children,\n className,\n containerProps,\n tabContentLabelProps,\n errorBoundaryProps,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const printing = usePrinting();\n const annexPath = useCurrentPath();\n const documentTitle = useAnnexState(annexPath, (state) =>\n state === null ? null : state.documentTitle,\n );\n\n if (documentTitle === undefined) {\n warnOnce(\n `Annex: At '${annexPath.toString()}': \\`documentTitle\\` ` +\n \"should be set manually since either `title` or `subtitle` is not a \" +\n \"string.\",\n );\n }\n\n return (\n <div\n {...containerProps}\n className={cx(\n prefix(\"annexes__annex-container\"),\n containerProps?.className,\n )}\n >\n <TabContent\n className={cx(prefix(\"annexes__annex\"), className)}\n value={annexPath.toString()}\n tabContentLabelProps={{\n ...tabContentLabelProps,\n className: cx(\n prefix(\"annexes__annex-label\"),\n tabContentLabelProps?.className,\n ),\n }}\n {...otherProps}\n ref={forwardedRef}\n >\n <ErrorBoundary {...errorBoundaryProps}>\n <DocumentTitle\n title={printing ? undefined : (documentTitle ?? undefined)}\n >\n <FormAppStatus disabled={disabled} readOnly={readOnly}>\n <FormAppIssueMessages issueMessages={issueMessages}>\n <Suspense fallback={<Spinner size=\"xl\" color=\"primary\" />}>\n {children}\n </Suspense>\n </FormAppIssueMessages>\n </FormAppStatus>\n </DocumentTitle>\n </ErrorBoundary>\n </TabContent>\n </div>\n );\n});\n","import { AbsolutePath } from \"@ostack.tech/kform\";\nimport { useFormController, useFormManager } from \"@ostack.tech/kform-react\";\nimport { useToastManager } from \"@ostack.tech/ui\";\nimport {\n fileOpen,\n type FileSystemHandle,\n type FileWithHandle,\n supported,\n type WellKnownDirectory,\n} from \"browser-fs-access\";\nimport { type ReactNode, useMemo } from \"react\";\n\nimport { useStartIssuesNavigation } from \"../components/FormApp\";\nimport { useLocale } from \"../providers/LocalizationProvider\";\n\n/**\n * Options that can be passed to the {@link useFormLoader} hook, or to its\n * resulting `load` function.\n */\nexport interface FormLoaderOptions<T = unknown> {\n /**\n * Function used to decode the form, given its file.\n *\n * If decoding a text-based format, one may use `await file.text()` to get the\n * content of the file as a string.\n *\n * @param file File containing the form to decode.\n * @returns Decoded form value.\n */\n decode?: (file: FileWithHandle) => PromiseLike<T>;\n /**\n * Path of the value being loaded.\n *\n * @default AbsolutePath.ROOT\n */\n path?: string | AbsolutePath;\n /** Acceptable file extensions. */\n extensions?: string[];\n /** Acceptable MIME types. */\n mimeTypes?: string[];\n /** Suggested file description. */\n description?: string;\n /** Directory to present when starting to load. */\n startIn?: WellKnownDirectory | FileSystemHandle;\n /**\n * By specifying an ID, the user agent can remember different directories for\n * different IDs.\n */\n id?: string;\n /**\n * Whether to set the form as pristine when it is loaded.\n *\n * @default true\n */\n setPristineOnLoad?: boolean;\n /**\n * Whether to validate the form (and show the issues panel) when it is loaded.\n *\n * @default true\n */\n validateOnLoad?: boolean;\n /**\n * Message to show in a toast when successfully loading a form from a file.\n * Can be set to `null` to not show any message.\n *\n * @param file Loaded file.\n * @returns Message to show in a toast.\n */\n successMessage?: ReactNode | ((file: FileWithHandle) => ReactNode);\n /**\n * Message to show in a toast when an error occurs while loading the form from\n * a file. Can be set to `null` to not show any message.\n *\n * @param file File from which the load was attempted (or `null` if the file\n * could not be accessed).\n * @param error Error that occurred.\n * @returns Message to show in a toast.\n */\n errorMessage?:\n | ReactNode\n | ((file: FileWithHandle | null, error: unknown) => ReactNode);\n}\n\n/** Result of the {@link useFormLoader} hook. */\nexport interface FormLoaderResult<T> {\n /**\n * Function used to load the form.\n *\n * @param options Options used for loading the form.\n * @returns Promise which resolves once the form has been loaded.\n */\n load: (options?: FormLoaderOptions<T>) => Promise<void>;\n /** Whether the browser supports modern file system APIs used for loading. */\n supportsFileSystemAPIs: boolean;\n}\n\n/** Hook exposing a function used to load the form from a file. */\nexport function useFormLoader<T = unknown>({\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n}: FormLoaderOptions<T> = {}): FormLoaderResult<T> {\n const [locale] = useLocale();\n const formManager = useFormManager();\n const { _setState } = useFormController();\n const { addToast } = useToastManager();\n const startIssuesNavigation = useStartIssuesNavigation();\n\n return useMemo(() => {\n async function load({\n decode,\n path = AbsolutePath.ROOT,\n extensions,\n mimeTypes,\n description,\n startIn,\n id = \"\",\n setPristineOnLoad = true,\n validateOnLoad = true,\n successMessage,\n errorMessage,\n }: FormLoaderOptions<T>) {\n if (!decode) {\n throw new Error(\"No `decode` function was provided.\");\n }\n if (successMessage === undefined) {\n successMessage = locale.LoadAction.successMessage;\n }\n if (errorMessage === undefined) {\n errorMessage = locale.LoadAction.errorMessage;\n }\n\n const validationModeIsAuto =\n formManager.autoValidationStatus !== \"inactive\";\n let file: FileWithHandle | null = null;\n try {\n file = await fileOpen({\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n });\n\n _setState({ loading: true } as any);\n const formValue = await decode(file);\n\n // Set validation mode as manual prior to loading the file\n if (validationModeIsAuto) {\n await formManager.setValidationMode(\"manual\");\n }\n\n await formManager.set(path, formValue);\n if (setPristineOnLoad) {\n await formManager.setPristine(path);\n }\n if (validateOnLoad) {\n await startIssuesNavigation();\n }\n\n _setState(\n (state: any) =>\n ({\n latestFileHandles: {\n ...state.latestFileHandles,\n [id]: file!.handle ?? null,\n },\n }) as any,\n );\n\n const message =\n typeof successMessage === \"function\"\n ? successMessage(file)\n : successMessage;\n if (message != null) {\n addToast(message, { severity: \"success\" });\n }\n } catch (err) {\n // User aborted\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(err);\n }\n const message =\n typeof errorMessage === \"function\"\n ? errorMessage(file, err)\n : errorMessage;\n if (message != null) {\n addToast(message, { severity: \"danger\" });\n }\n } finally {\n // Reset validation mode\n if (validationModeIsAuto) {\n await formManager.setValidationMode(\"auto\");\n }\n\n _setState({ loading: false } as any);\n }\n }\n\n return {\n load: (options = {}) =>\n load({\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n ...options,\n }),\n supportsFileSystemAPIs: supported,\n };\n }, [\n _setState,\n formManager,\n startIssuesNavigation,\n locale.LoadAction,\n addToast,\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n ]);\n}\n\n/** Hook exposing whether the form is currently being loaded. */\nexport function useFormIsLoading() {\n return useFormController().useState((state) => (state as any).loading);\n}\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { CurrentPath, useFormattedValue } from \"@ostack.tech/kform-react\";\nimport { usePrinting, useStartPrintingTask } from \"@ostack.tech/ui\";\nimport {\n type ReactNode,\n useCallback,\n useDeferredValue,\n useEffect,\n} from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedAnnexObject,\n useAnnexesContext,\n} from \"./AnnexesContext.ts\";\n\n/** Properties of the `AnnexRegistrar` component. */\nexport interface AnnexRegistrarProps extends ResolvedAnnexObject {\n index?: number;\n}\n\n/** Component used to register a form annex. */\nexport function AnnexRegistrar({\n path,\n title,\n subtitle,\n description,\n issuesPanelLabel,\n itemTitle,\n itemIssuesPanelLabel,\n index,\n documentTitle,\n}: AnnexRegistrarProps) {\n const store = useAnnexesContext();\n\n const printing = usePrinting();\n const finishPrintingTask = useStartPrintingTask();\n const [isNull = true, controller] = useFormattedValue(\n path.append(AbsolutePathFragment.RecursiveWildcard),\n {\n enabled: !useFormIsLoading(),\n onInitialized: finishPrintingTask,\n format: useCallback((value: unknown) => value === null, []),\n },\n );\n const isRepetitive = index != null;\n const absolutePath = controller.usePath();\n const schema = controller.useSchema();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n const dirty = controller.useDirty();\n const value = controller.useValue();\n const deferredValue = useDeferredValue(value);\n const relevantValue = printing ? value : deferredValue;\n const deferredIssuesToDisplay = useDeferredValue(\n controller.useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n const actualTitle = isRepetitive\n ? typeof itemTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : itemTitle(relevantValue, index)\n : itemTitle === undefined\n ? (title as ReactNode)\n : itemTitle\n : typeof title === \"function\"\n ? relevantValue === undefined\n ? null\n : title(relevantValue)\n : title;\n const actualSubtitle =\n typeof subtitle === \"function\"\n ? relevantValue === undefined\n ? null\n : subtitle(relevantValue, index)\n : subtitle;\n const actualDocumentTitle =\n typeof documentTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : documentTitle(relevantValue, index)\n : documentTitle === undefined\n ? (actualTitle === null || typeof actualTitle === \"string\") &&\n (actualSubtitle == null || typeof actualSubtitle === \"string\")\n ? [actualTitle, actualSubtitle].filter((s) => s).join(\" — \")\n : undefined\n : documentTitle;\n\n useEffect(() => {\n if (exists) {\n const { registerAnnexState } = store.getState().actions;\n registerAnnexState(absolutePath, {\n path: absolutePath,\n schema,\n isNull,\n dirty,\n deferredIssuesToDisplay,\n deferredDisplayStatus,\n isRepetitive,\n title: actualTitle,\n subtitle: actualSubtitle,\n documentTitle: actualDocumentTitle,\n description,\n });\n }\n }, [\n absolutePath,\n deferredDisplayStatus,\n deferredIssuesToDisplay,\n description,\n dirty,\n exists,\n isNull,\n isRepetitive,\n actualSubtitle,\n actualTitle,\n schema,\n store,\n subtitle,\n title,\n actualDocumentTitle,\n ]);\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>\n {isRepetitive ? (\n typeof itemIssuesPanelLabel === \"function\" ? (\n deferredValue === undefined ? null : (\n itemIssuesPanelLabel(deferredValue, index)\n )\n ) : itemIssuesPanelLabel === undefined ? (\n (actualSubtitle ?? index + 1)\n ) : (\n itemIssuesPanelLabel\n )\n ) : issuesPanelLabel ? (\n typeof issuesPanelLabel === \"function\" ? (\n deferredValue === undefined ? null : (\n issuesPanelLabel(deferredValue)\n )\n ) : (\n issuesPanelLabel\n )\n ) : (\n <>\n {actualTitle}\n {actualSubtitle && <> — {actualSubtitle}</>}\n </>\n )}\n </CurrentPath>,\n );\n\n return null;\n}\n","import {\n AbsolutePathFragment,\n sliceTable,\n type Table,\n type TableRowId,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n InvalidPathError,\n useFormattedValue,\n} from \"@ostack.tech/kform-react\";\nimport { useStartPrintingTask } from \"@ostack.tech/ui\";\nimport { useCallback, useDeferredValue, useEffect } from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedAnnexObject,\n useAnnexesContext,\n} from \"./AnnexesContext.ts\";\nimport { AnnexRegistrar } from \"./AnnexRegistrar.tsx\";\n\n/** Properties of the `RepetitiveAnnexRegistrar` component. */\nexport interface RepetitiveAnnexRegistrarProps extends ResolvedAnnexObject {}\n\n/** Component used to register a repetitive form annex. */\nexport function RepetitiveAnnexRegistrar({\n path,\n maxAnnexes,\n ...annexProps\n}: RepetitiveAnnexRegistrarProps) {\n const store = useAnnexesContext();\n\n const finishPrintingTask = useStartPrintingTask();\n const [rowIds, controller] = useFormattedValue(path.parent(), {\n enabled: !useFormIsLoading(),\n onInitialized: finishPrintingTask,\n format: useCallback(\n (value?: Table | null): TableRowId[] =>\n value == null ? [] : sliceTable(value).map(([id]) => id),\n [],\n ),\n });\n const schema = controller.useSchema();\n const absolutePath = controller.usePath();\n const deferredIssuesToDisplay = useDeferredValue(\n controller.useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n if (schema.typeInfo.name !== \"Table\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected (possibly nullable) table schema, \" +\n \"but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n useEffect(() => {\n const { registerRepetitiveAnnexState } = store.getState().actions;\n registerRepetitiveAnnexState(absolutePath, {\n rowIds,\n maxAnnexes,\n path: absolutePath,\n schema,\n deferredIssuesToDisplay,\n });\n }, [\n absolutePath,\n deferredDisplayStatus,\n deferredIssuesToDisplay,\n maxAnnexes,\n rowIds,\n schema,\n store,\n ]);\n\n if (\n typeof annexProps.title === \"function\" ||\n typeof annexProps.issuesPanelLabel === \"function\"\n ) {\n throw new Error(\n \"Repetitive annexes must not set `title` or `issuesPanelLabel` as a \" +\n \"function. Use `itemTitle` or `itemIssuesPanelLabel` instead.\",\n );\n }\n\n const actualIssuesPanelLabel = annexProps.issuesPanelLabel\n ? annexProps.issuesPanelLabel\n : annexProps.title;\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>{actualIssuesPanelLabel}</CurrentPath>,\n );\n\n return rowIds?.map((rowId, i) => (\n <AnnexRegistrar\n key={rowId}\n path={absolutePath.append(new AbsolutePathFragment.Id(rowId))}\n index={i}\n {...annexProps}\n />\n ));\n}\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n Path,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n useFormManager,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport { cx, Tabs } from \"@ostack.tech/ui\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useMemo,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { Annex, type AnnexProps } from \"./Annex.tsx\";\nimport { AnnexesContext, useCreateAnnexesContext } from \"./AnnexesContext.ts\";\nimport { AnnexRegistrar } from \"./AnnexRegistrar.tsx\";\nimport { RepetitiveAnnexRegistrar } from \"./RepetitiveAnnexRegistrar.tsx\";\n\n/** Properties of the annexes component. */\nexport interface AnnexesProps extends Omit<\n ComponentPropsWithoutRef<typeof Tabs>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"showAllTabsWhilePrinting\"\n> {\n /** Base path for all declared annexes. */\n path?: string | Path;\n /**\n * List of all annexes. When not provided, the list of annexes is obtained\n * from the direct children `Annex` components.\n */\n annexes?: AnnexObject[];\n /** Default active annex. */\n defaultActiveAnnex?: string | Path;\n /** Controlled active annex. */\n activeAnnex?: string | Path;\n /**\n * Function called whenever the active annex changes.\n *\n * @param activeAnnex Path of the new active annex.\n */\n onActiveAnnexChange?: (activeAnnexPath: AbsolutePath | null) => void;\n /**\n * Function called when a new annex is added.\n *\n * @param newAnnexPath Path of the new annex.\n */\n onAnnexAdd?: (newAnnexPath: AbsolutePath) => void;\n /**\n * Function called when an annex is removed.\n *\n * @param removedAnnexPath Path of the removed annex.\n */\n onAnnexRemove?: (removedAnnexPath: AbsolutePath) => void;\n children?: ReactNode;\n}\n\n/** Object representation of an annex. */\nexport interface AnnexObject<T = any> {\n /**\n * Annex path. This path may contain a single wildcard (`*`) at the end, when\n * the elements of a collection should be counted as annexes. Otherwise, the\n * path may contain no other wildcards.\n */\n path?: string | Path;\n /** Annex's title. */\n title?: ReactNode | ((value: T) => ReactNode);\n /** Annex's subtitle. */\n subtitle?: ReactNode | ((value: T, index?: number) => ReactNode);\n /** Annex's description. */\n description?: ReactNode;\n /**\n * Annex's label in the issues panel. The `title` and `subtitle` are used by\n * default.\n */\n issuesPanelLabel?: ReactNode | ((value: T) => ReactNode);\n itemTitle?: ReactNode | ((value: T, index: number) => ReactNode);\n /**\n * Issues panel label for each annex of a collection of annexes. The\n * `subtitle` and index of the item are used by default.\n */\n itemIssuesPanelLabel?: ReactNode | ((value: T, index: number) => ReactNode);\n /**\n * Title of the annex as a string to display in the document's title.\n *\n * Defaults to the `title` together with the `subtitle` (if it exists) when\n * they are strings.\n *\n * A warning is printed if either the title or the subtitle are defined but\n * aren't strings and `documentTitle` is not provided.\n */\n documentTitle?: string | null | ((value: T, index?: number) => string | null);\n /**\n * Maximum number of annexes matching this path that can be added, when\n * counting collection elements as annexes. By default, if the collection has\n * a `MaxSize` validation, then its value is used.\n */\n maxAnnexes?: number;\n /**\n * Function called when an annex matching this path is being added to choose\n * the value that should be added.\n *\n * The default value being added is provided as an argument and may be edited\n * if required.\n *\n * The value to be added should be returned, or a promise that resolves with\n * said value.\n *\n * To prevent an annex from being added, return `undefined`/`null` (or a\n * promise which resolves with `undefined`/`null`).\n *\n * @param value - Value being added, can be edited.\n * @returns Value to be added, `undefined`/`null` if the annex shouldn't be\n * added (or a promise that resolves with said values).\n */\n getValue?: (value: T) => T | null | undefined | Promise<T | null | undefined>;\n}\n\n/** Root component used to render form annexes. */\nexport const Annexes = forwardRef<ComponentRef<typeof Tabs>, AnnexesProps>(\n function Annexes(\n {\n path,\n annexes,\n defaultActiveAnnex,\n activeAnnex,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n variant = \"annexes\",\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n ) {\n const prefix = usePrefix();\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n\n annexes ??= Children.toArray(children)\n .filter(\n (child): child is ReactElement<AnnexProps, typeof Annex> =>\n isValidElement(child) && child.type === Annex,\n )\n .map((annex) => ({\n path: annex.props.path,\n title: annex.props.title,\n subtitle: annex.props.subtitle,\n description: annex.props.description,\n issuesPanelLabel: annex.props.issuesPanelLabel,\n itemTitle: annex.props.itemTitle,\n itemIssuesPanelLabel: annex.props.itemIssuesPanelLabel,\n documentTitle: annex.props.documentTitle,\n maxAnnexes: annex.props.maxAnnexes,\n getValue: annex.props.getValue,\n }));\n\n // Provided annexes but with absolute paths\n const resolvedAnnexes = useMemo(\n () =>\n annexes.map((annex) => ({\n ...annex,\n path: absolutePath.resolve(annex.path ?? Path.CURRENT),\n })),\n [absolutePath, annexes],\n );\n\n // Refuse non-existent paths\n if (!formManager.isValidPath(absolutePath)) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Annexes base path must only contain ids.\");\n }\n // Validate annex paths\n for (const annex of resolvedAnnexes) {\n // Refuse non-existent paths\n if (!formManager.isValidPath(annex.path)) {\n throw new Error(`Invalid path: '${annex.path.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only, or identifiers\n // followed by a wildcard\n if (\n annex.path.fragments.some(\n (frag, i, { length }) =>\n !(frag instanceof AbsolutePathFragment.Id) &&\n (frag !== AbsolutePathFragment.Wildcard || i !== length - 1),\n )\n ) {\n throw new Error(\n \"Annex path must either only contain ids, or ids followed by a \" +\n \"single wildcard at the end.\",\n );\n }\n }\n\n const store = useCreateAnnexesContext({\n formManager,\n basePath: absolutePath,\n resolvedAnnexes,\n defaultActiveAnnex,\n activeAnnex,\n onActiveAnnexChange,\n onAnnexAdd,\n onAnnexRemove,\n });\n\n const activeAnnexString = useStore(\n store,\n (state) => state.activeAnnex?.toString() ?? \"\",\n );\n const handleValueChange = useCallback(\n (value: string) => store.getState().actions.setActiveAnnex(value),\n [store],\n );\n\n return (\n <CurrentPath path={absolutePath}>\n <AnnexesContext.Provider value={store}>\n {resolvedAnnexes.map((annex) =>\n annex.path.lastFragment === AbsolutePathFragment.Wildcard ? (\n <RepetitiveAnnexRegistrar\n key={annex.path.toString()}\n {...annex}\n />\n ) : (\n <AnnexRegistrar key={annex.path.toString()} {...annex} />\n ),\n )}\n\n <Tabs\n className={cx(prefix(\"annexes\"), className)}\n variant={variant}\n activationMode=\"manual\"\n value={activeAnnexString}\n onValueChange={handleValueChange}\n showAllTabsWhilePrinting\n {...otherProps}\n ref={forwardedRef}\n >\n {children}\n </Tabs>\n </AnnexesContext.Provider>\n </CurrentPath>\n );\n },\n);\n","import { type AbsolutePath, ValidationFailure } from \"@ostack.tech/kform\";\nimport {\n AtPathError,\n type LocatedValidationInfo,\n} from \"@ostack.tech/kform-react\";\nimport { useErrorReporter } from \"@ostack.tech/ui\";\nimport { useEffect } from \"react\";\n\ntype ReportValidationFailuresInfo = Pick<\n LocatedValidationInfo,\n \"path\" | \"issues\"\n>;\n\nclass ValidationFailureError extends AtPathError {\n constructor(path: AbsolutePath, issue: ValidationFailure) {\n super(path, `Failed to run validation '${issue.validation}'`);\n this.name = this.constructor.name;\n this.stack += `\\nCaused by: ${issue.stackTrace}`;\n }\n}\n\n/** Hook used to report validation failures that occur. */\nexport function useReportValidationFailures(\n info?: ReportValidationFailuresInfo[],\n) {\n const reportError = useErrorReporter();\n useEffect(() => {\n if (info) {\n for (const { path, issues } of info) {\n for (const issue of issues) {\n if (issue instanceof ValidationFailure) {\n reportError(new ValidationFailureError(path, issue));\n }\n }\n }\n }\n }, [info, reportError]);\n}\n","import type {\n AbsolutePath,\n FormManager,\n Schema,\n SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport { EMPTY_STORE, useConstant } from \"@ostack.tech/ui\";\nimport { createContext, useContext, useEffect } from \"react\";\nimport { createStore, useStore } from \"zustand\";\n\n/** Value of the control field context. */\nexport type ControlFieldContextValue = ControlFieldStore;\n\n/** State of the control field. */\nexport interface ControlFieldState {\n controlStates: Record<string, ControlState>;\n}\n\n/** State of a control accessible to the whole field. */\nexport interface ControlState {\n formManager: FormManager;\n schema: Schema;\n path: AbsolutePath;\n exists: boolean;\n deferredIssuesToDisplay: SealedValidationIssue[];\n}\n\n/** Control field store. */\nexport type ControlFieldStore = ReturnType<typeof useCreateControlFieldContext>;\n\n/** Control field context. */\nexport const ControlFieldContext =\n createContext<ControlFieldContextValue | null>(null);\n\n/** Hook which creates the control field context value. */\nexport function useCreateControlFieldContext() {\n return useConstant(() =>\n createStore<ControlFieldState>(() => ({\n controlStates: {},\n })),\n );\n}\n\n/** Hook returning the control field's context value. */\nfunction useControlFieldContext(): ControlFieldContextValue | null {\n return useContext(ControlFieldContext);\n}\n\n/** Hook that returns access to the control field's store. */\nexport function useControlFieldStore<T>(\n selector: (state: Partial<ControlFieldState>) => T,\n): T {\n return useStore(useControlFieldContext() ?? EMPTY_STORE, selector);\n}\n\n/** Hook exposing whether a component is being rendered within a control field. */\nexport function useIsInControlField(): boolean {\n return useControlFieldContext() !== null;\n}\n\n/**\n * Hook that makes a control field aware of a controller.\n *\n * The passed `controller` object should not be different on every render.\n */\nexport function useRegisterControllerWithinControlField<T = unknown>(\n controller: Controller<T>,\n deferredIssuesToDisplay: SealedValidationIssue[],\n) {\n const store = useControlFieldContext();\n const formManager = controller.useFormManager();\n const path = controller.usePath();\n const schema = controller.useSchema();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n useEffect(() => {\n if (store) {\n const pathStr = path.toString();\n store.setState((state) => ({\n controlStates: {\n ...state.controlStates,\n [pathStr]: {\n formManager,\n schema,\n path,\n exists,\n deferredIssuesToDisplay,\n },\n },\n }));\n return () => {\n store.setState(\n ({ controlStates: { [pathStr]: _, ...controlStates } }) => ({\n controlStates,\n }),\n );\n };\n }\n }, [deferredIssuesToDisplay, exists, formManager, path, schema, store]);\n}\n","import { Path } from \"@ostack.tech/kform\";\nimport { CurrentPath, useFormManager } from \"@ostack.tech/kform-react\";\nimport { Field } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useEffect,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport {\n ControlFieldContext,\n useCreateControlFieldContext,\n} from \"./ControlFieldContext.ts\";\n\n/** Properties of the control field component. */\nexport interface ControlFieldProps extends ComponentPropsWithoutRef<\n typeof Field\n> {\n /** Path of the field; inner control paths will be relative to this path. */\n path?: string | Path;\n /**\n * Whether to show the control field.\n *\n * The component will, by default, automatically reset its inner controls when\n * the control field becomes hidden.\n *\n * @default true\n */\n shown?: boolean;\n /**\n * Whether to reset the inner controls when the control field becomes hidden.\n *\n * @default true\n */\n resetOnHide?: boolean;\n /**\n * Whether to set inner controls as untouched when the control field becomes\n * hidden.\n *\n * @default resetOnHide\n */\n setUntouchedOnHide?: boolean;\n /**\n * Whether to set inner controls as pristine when the control field becomes\n * hidden.\n *\n * @default resetOnHide\n */\n setPristineOnHide?: boolean;\n}\n\n/**\n * Component used to group controls with a label, helper text, and/or feedback.\n *\n * The component can be conditionally shown via the `shown` property which, by\n * default, when changing from `true` to `false` will reset its inner controls.\n *\n * Added labels automatically \"point\" to the control and are set to \"required\"\n * when requested by the control.\n *\n * Aria descriptions and error messages are set on the control based on the\n * provided helper texts or feedbacks.\n */\nexport const ControlField = forwardRef<\n ComponentRef<typeof Field>,\n ControlFieldProps\n>(function ControlField(\n {\n path = Path.CURRENT,\n shown = true,\n resetOnHide = true,\n setUntouchedOnHide = resetOnHide,\n setPristineOnHide = resetOnHide,\n ...otherProps\n },\n forwardedRef,\n) {\n const formManager = useFormManager();\n\n // Controllers registered within the control field\n const store = useCreateControlFieldContext();\n\n // Reset registered controllers when `shown` becomes `false`\n const controlStates = useStore(store, (state) => state.controlStates);\n useEffect(() => {\n if (!shown) {\n for (const controlState of Object.values(controlStates)) {\n const { formManager, path, exists } = controlState;\n if (exists) {\n if (resetOnHide) {\n void formManager.reset(path);\n }\n if (setUntouchedOnHide) {\n void formManager.setUntouched(path);\n }\n if (setPristineOnHide) {\n void formManager.setPristine(path);\n }\n }\n }\n }\n }, [\n controlStates,\n formManager,\n resetOnHide,\n setPristineOnHide,\n setUntouchedOnHide,\n shown,\n store,\n ]);\n\n return (\n shown && (\n <CurrentPath path={path}>\n <ControlFieldContext.Provider value={store}>\n <Field {...otherProps} ref={forwardedRef} />\n </ControlFieldContext.Provider>\n </CurrentPath>\n )\n );\n});\n","import type {\n AbsolutePath,\n Schema,\n SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport {\n useDisplayIssueCodesInIssueMessages,\n useRegisteredIssueMessage,\n} from \"../FormApp\";\n\n/** Properties of the issue message component. */\nexport interface IssueMessageProps {\n displayIssueCode?: boolean;\n unknownErrorMessage?: ReactNode;\n unknownWarningMessage?: ReactNode;\n path: AbsolutePath;\n issue: SealedValidationIssue;\n schema: Schema;\n issueCodeProps?: ComponentPropsWithRef<\"span\">;\n}\n\n/** Single issue message within the issue messages or issues panel components. */\nexport function IssueMessage({\n path,\n issue,\n schema,\n displayIssueCode,\n unknownErrorMessage,\n unknownWarningMessage,\n issueCodeProps,\n}: IssueMessageProps) {\n const [locale] = useLocale();\n unknownErrorMessage ??= locale.IssueMessages.unknownErrorMessage;\n unknownWarningMessage ??= locale.IssueMessages.unknownWarningMessage;\n\n let message = useRegisteredIssueMessage(path, issue.code);\n const unknownIssue = message == null;\n if (unknownIssue) {\n message =\n issue.severity === \"error\" ? unknownErrorMessage : unknownWarningMessage;\n // if (process.env.NODE_ENV !== \"production\") {\n // warnOnce(\n // `At '${path.toString()}': no message found for ` +\n // `issue with code: '${issue.code}'.`,\n // );\n // }\n }\n\n const globalDisplayIssueCodes = useDisplayIssueCodesInIssueMessages();\n displayIssueCode ??= globalDisplayIssueCodes;\n\n return (\n <CurrentPath path={path}>\n {typeof message === \"function\"\n ? message(issue.data ?? {}, schema, path)\n : message}\n {(displayIssueCode || unknownIssue) && (\n <span {...issueCodeProps}>({issue.code})</span>\n )}\n </CurrentPath>\n );\n}\n","import type {\n AbsolutePath,\n Path,\n Schema,\n SealedValidationIssue,\n ValidationIssueData,\n} from \"@ostack.tech/kform\";\nimport {\n useFormManager,\n useIssuesTracker,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport { Feedback, FeedbackList } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useDeferredValue,\n useMemo,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useReportValidationFailures } from \"../../utils/useReportValidationFailures.ts\";\nimport { useIsInControlField } from \"../ControlField\";\nimport { useControlFieldStore } from \"../ControlField/ControlFieldContext.ts\";\nimport { FormAppIssueMessages } from \"../FormApp\";\nimport { IssueMessage } from \"../IssueMessage\";\n\n/** Value of an issue message. */\nexport type IssueMessageValue =\n | ReactNode\n | ((\n issueData: ValidationIssueData,\n schema: Schema,\n path: AbsolutePath,\n ) => ReactNode);\n\n/** Mapping of issue message codes to their respective message. */\nexport type IssueMessagesByCode = Record<string, IssueMessageValue>;\n\n/** Properties of the issue messages component. */\nexport interface IssueMessagesProps extends ComponentPropsWithoutRef<\n typeof FeedbackList\n> {\n /** Path of the value for which to show issues. */\n path?: string | Path;\n /**\n * Issues to show, associated with the provided path. If not provided, the\n * component will query the issues from the form manager.\n */\n issues?: SealedValidationIssue[];\n /** Mapping from an issue's code to its message. */\n messages?: IssueMessagesByCode;\n /**\n * Whether to display issue codes together with each issue message.\n *\n * This property can also be set globally via the `displayIssueCodes` property\n * of the `FormApp`.\n */\n displayIssueCodes?: boolean;\n /**\n * Message to show for an error that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownErrorMessage?: ReactNode;\n /**\n * Message to show for a warning that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownWarningMessage?: ReactNode;\n /**\n * Whether to render the issue messages \"unwrapped\", i.e. outside a containing\n * `FeedbackList`.\n *\n * This is useful together with components such as the `DateRangeControl`\n * where you might want to show issues for multiple paths, all within the same\n * `FeedbackList`:\n *\n * ```tsx\n * <FeedbackList>\n * <IssueMessages path=\"startDate\" unwrapped />\n * <IssueMessages path=\"endDate\" unwrapped />\n * </FeedbackList>;\n * ```\n */\n unwrapped?: boolean;\n}\n\n/**\n * Component used to display all issues associated with the relevant path.\n *\n * Issue messages are automatically read from the scope (typically provided by\n * setting the `issueMessages` property of a `FormApp`, `Annex`, or\n * `FormPage`).\n *\n * Messages may also be passed directly to this component via the `messages`\n * property.\n *\n * If `path` contains an issue without an associated issue message, a generic\n * message is displayed together with a console warning.\n */\nexport const IssueMessages = forwardRef<\n ComponentRef<typeof FeedbackList>,\n IssueMessagesProps\n>(function IssueMessages(\n {\n path,\n issues,\n messages,\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n unwrapped,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const isInControlField = useIsInControlField();\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n const { info } = useIssuesTracker(absolutePath, {\n enabled: !issues && !isInControlField,\n });\n const messagesToRegister = useMemo(\n () => messages && { [absolutePath.toString()]: messages },\n [absolutePath, messages],\n );\n\n const relevantControlState = useControlFieldStore((state) =>\n isInControlField ? state.controlStates?.[absolutePath.toString()] : null,\n );\n const deferredTrackedIssues = useDeferredValue(\n useMemo(() => info?.flatMap((info) => info.issues) ?? [], [info]),\n );\n const deferredIssuesToDisplay = useMemo(\n () =>\n issues ??\n (isInControlField\n ? (relevantControlState?.deferredIssuesToDisplay ?? [])\n : deferredTrackedIssues),\n [\n deferredTrackedIssues,\n isInControlField,\n issues,\n relevantControlState?.deferredIssuesToDisplay,\n ],\n );\n useReportValidationFailures(\n useMemo(\n () => [{ path: absolutePath, issues: deferredIssuesToDisplay }],\n [absolutePath, deferredIssuesToDisplay],\n ),\n );\n\n const schema = useMemo(\n () => relevantControlState?.schema ?? formManager.schema(absolutePath),\n [absolutePath, formManager, relevantControlState?.schema],\n );\n\n const feedbackNodes = useMemo(\n () =>\n deferredIssuesToDisplay.map((issue, i) => (\n <Feedback key={i} type={issue.severity}>\n <IssueMessage\n path={absolutePath}\n issue={issue}\n schema={schema}\n displayIssueCode={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n issueCodeProps={{ className: prefix(\"issue-messages__issue-code\") }}\n />\n </Feedback>\n )),\n [\n deferredIssuesToDisplay,\n absolutePath,\n schema,\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n prefix,\n ],\n );\n\n return (\n <FormAppIssueMessages issueMessages={messagesToRegister}>\n {unwrapped ? (\n feedbackNodes\n ) : (\n <FeedbackList {...otherProps} ref={forwardedRef}>\n {feedbackNodes}\n </FeedbackList>\n )}\n </FormAppIssueMessages>\n );\n});\n","import { AbsolutePath, type Path } from \"@ostack.tech/kform\";\nimport { CurrentPath, useResolvedPath } from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n FeedbackPopover,\n useControllableState,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useIsInControlField } from \"../ControlField\";\nimport { useOnPathFocus } from \"../FormApp\";\n\n/** Properties of the issues popover component. */\nexport interface IssuesPopoverProps extends ComponentPropsWithoutRef<\n typeof FeedbackPopover\n> {\n path?: string | Path;\n /**\n * Paths relevant to this issues popover. When one of the relevant paths\n * becomes active, the popover will automatically open. Defaults to `[path]`\n * (or `[<current path>]` if no `path` is provided).\n */\n relevantPaths?: (string | Path)[];\n}\n\n/** Component used to display issues within a popover. */\nexport const IssuesPopover = forwardRef<\n ComponentRef<typeof FeedbackPopover>,\n IssuesPopoverProps\n>(function IssuesPopover(\n {\n path,\n relevantPaths,\n defaultOpen,\n open: controlledOpen,\n onOpenChange,\n label,\n ...otherProps\n },\n forwardedRef,\n) {\n const [locale] = useLocale();\n label ??= locale.IssuesPopover.label;\n\n const absolutePath = useResolvedPath(path);\n const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);\n const isInControlField = useIsInControlField();\n\n // Open popover when active path matches the popover's path (unneeded when\n // within a control field)\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n if (\n !isInControlField &&\n (relevantPaths ?? [absolutePath]).some((path) =>\n focusedPath.equals(new AbsolutePath(path)),\n )\n ) {\n setOpen(true);\n }\n },\n [isInControlField, relevantPaths, absolutePath, setOpen],\n ),\n );\n\n return (\n <CurrentPath path={absolutePath}>\n <FeedbackPopover\n open={open}\n onOpenChange={combineEventHandlers(onOpenChange, setOpen)}\n label={label}\n {...otherProps}\n ref={forwardedRef}\n />\n </CurrentPath>\n );\n});\n","import type { DisplayStatus } from \"@ostack.tech/kform\";\nimport type { ControlStatus } from \"@ostack.tech/ui\";\n\n/** Transforms ostack/KForm's display status into ostack/UI's control status. */\nexport function displayStatusToControlStatus(\n displayStatus: DisplayStatus | undefined,\n): ControlStatus | undefined {\n switch (displayStatus) {\n case \"error\":\n return \"invalid\";\n case \"warning\":\n return \"warned\";\n default:\n return undefined;\n }\n}\n\n/** Transforms ostack/KForm's display status into a \"danger\" or \"warning\" colour. */\nexport function displayStatusToColor(\n displayStatus: DisplayStatus | undefined,\n): \"danger\" | \"warning\" | undefined {\n switch (displayStatus) {\n case \"error\":\n return \"danger\";\n case \"warning\":\n return \"warning\";\n default:\n return undefined;\n }\n}\n","import {\n faChevronDown,\n faChevronUp,\n faTrash,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport {\n AbsolutePath,\n AbsolutePathFragment,\n nullableSchemaInnerSchema,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n FormContext,\n useFormContext,\n useFormManager,\n} from \"@ostack.tech/kform-react\";\nimport {\n Button,\n combineEventHandlers,\n controlStatusToAccent,\n cx,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n IconButton,\n useAlertDialog,\n useCombinedRef,\n useControllableState,\n useMediaBreakpointUp,\n VisuallyHidden,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type Dispatch,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { visiblyFocus } from \"../../utils/useControlAutofocus.ts\";\nimport {\n useFormIsDisabled,\n useFormIsReadOnly,\n useIssuesDisplayMode,\n useOnPathFocus,\n} from \"../FormApp\";\nimport { useResetFocus } from \"../FormApp/FormAppContext.ts\";\nimport {\n type ResolvedAnnexObject,\n useAnnexesContext,\n useAnnexState,\n} from \"./AnnexesContext.ts\";\nimport type { AnnexesManager } from \"./AnnexesManager.tsx\";\n\n/** Properties of the annexes' menu. */\nexport interface AnnexesMenuProps\n extends\n Pick<\n ComponentPropsWithoutRef<typeof AnnexesManager>,\n | \"menuButtonText\"\n | \"addAnnexText\"\n | \"removeAnnexButtonLabel\"\n | \"removeAnnexKeyboardHint\"\n | \"removeAnnexConfirmDialogTitle\"\n | \"removeAnnexConfirmDialogMessage\"\n | \"removeAnnexConfirmDialogOkText\"\n | \"removeAnnexConfirmDialogCancelText\"\n >,\n ComponentPropsWithoutRef<typeof DropdownMenu> {\n menuTriggerProps?: Omit<ComponentPropsWithRef<typeof Button>, \"icon\">;\n menuContentProps?: ComponentPropsWithRef<typeof DropdownMenuContent>;\n}\n\n/** Component that allows to navigate between, add, and remove annexes. */\nexport function AnnexesMenu({\n menuButtonText,\n addAnnexText,\n removeAnnexButtonLabel,\n removeAnnexKeyboardHint,\n removeAnnexConfirmDialogTitle,\n removeAnnexConfirmDialogMessage,\n removeAnnexConfirmDialogOkText,\n removeAnnexConfirmDialogCancelText,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n menuTriggerProps,\n menuContentProps,\n ...otherProps\n}: AnnexesMenuProps) {\n const prefix = usePrefix();\n const formIsReadOnly = useFormIsReadOnly();\n const store = useAnnexesContext();\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n const issuesDisplayMode = useIssuesDisplayMode();\n const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);\n const menuTriggerRef = useRef<HTMLButtonElement | null>(null);\n\n const activeAnnex = useStore(store, (state) => state.activeAnnex);\n const handleRadioGroupValueChange = useCallback(\n (value: string) =>\n store.getState().actions.setActiveAnnex(new AbsolutePath(value)),\n [store],\n );\n\n const annexes = useStore(store, (state) => state.annexes);\n const newItems = useMemo(\n () =>\n annexes.map((annex) => (\n <AnnexesMenuNewItem key={annex.path.toString()} annex={annex} />\n )),\n [annexes],\n );\n const tabStates = useStore(\n store,\n useShallow((state) => state.tabStates()),\n );\n\n // Focus menu trigger when focusing an annex that doesn't exist\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath: AbsolutePath) => {\n if (\n issuesDisplayMode === \"panel\" &&\n menuTriggerRef.current &&\n store\n .getState()\n .tablessStates()\n .some((state) => state.path.equals(focusedPath))\n ) {\n visiblyFocus(menuTriggerRef.current);\n resetFocus();\n }\n },\n [issuesDisplayMode, resetFocus, store],\n ),\n );\n\n const combinedMenuTriggerRef = useCombinedRef(\n menuTriggerRef,\n menuTriggerProps?.ref,\n );\n return (\n <DropdownMenu\n open={open}\n onOpenChange={combineEventHandlers(onOpenChange, setOpen)}\n modal={false}\n {...otherProps}\n >\n <DropdownMenuTrigger>\n <Button\n variant=\"ghost\"\n iconPlacement=\"end\"\n {...menuTriggerProps}\n className={cx(\n prefix(\"annexes__menu-trigger\"),\n menuTriggerProps?.className,\n )}\n icon={open ? faChevronUp : faChevronDown}\n iconProps={{ size: \"2xs\", ...menuTriggerProps?.iconProps }}\n ref={combinedMenuTriggerRef}\n >\n {menuTriggerProps?.children ?? menuButtonText}\n </Button>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent\n variant=\"subtle\"\n showArrow={false}\n sideOffset={-1}\n avoidCollisions={false}\n align=\"start\"\n {...menuContentProps}\n className={cx(prefix(\"annexes__menu\"), menuContentProps?.className)}\n >\n <DropdownMenuRadioGroup\n value={activeAnnex?.toString()}\n onValueChange={handleRadioGroupValueChange}\n >\n {tabStates.map((state) => (\n <AnnexesMenuItem\n key={state.path.toString()}\n removeAnnexButtonLabel={removeAnnexButtonLabel}\n removeAnnexKeyboardHint={removeAnnexKeyboardHint}\n removeAnnexConfirmDialogTitle={removeAnnexConfirmDialogTitle}\n removeAnnexConfirmDialogMessage={removeAnnexConfirmDialogMessage}\n removeAnnexConfirmDialogOkText={removeAnnexConfirmDialogOkText}\n removeAnnexConfirmDialogCancelText={\n removeAnnexConfirmDialogCancelText\n }\n path={state.path}\n setOpen={setOpen}\n menuRef={menuTriggerRef}\n />\n ))}\n </DropdownMenuRadioGroup>\n {!formIsReadOnly && (\n <DropdownMenuGroup label={isLargeScreen ? undefined : addAnnexText}>\n {isLargeScreen ? (\n <DropdownMenuSub>\n <DropdownMenuSubTrigger\n className={prefix(\"annexes__menu-add-annex\")}\n >\n {addAnnexText}\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent className={prefix(\"annexes__menu-new\")}>\n {newItems}\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n ) : (\n newItems\n )}\n </DropdownMenuGroup>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/** Properties of an item in the annexes' menu. */\ninterface AnnexesMenuItemProps extends Pick<\n ComponentPropsWithoutRef<typeof AnnexesManager>,\n | \"removeAnnexButtonLabel\"\n | \"removeAnnexKeyboardHint\"\n | \"removeAnnexConfirmDialogTitle\"\n | \"removeAnnexConfirmDialogMessage\"\n | \"removeAnnexConfirmDialogOkText\"\n | \"removeAnnexConfirmDialogCancelText\"\n> {\n path: AbsolutePath;\n setOpen: Dispatch<boolean>;\n menuRef: RefObject<HTMLButtonElement | null>;\n}\n\n/** Item in the annexes' menu. */\nfunction AnnexesMenuItem({\n removeAnnexButtonLabel,\n removeAnnexKeyboardHint,\n removeAnnexConfirmDialogTitle,\n removeAnnexConfirmDialogMessage,\n removeAnnexConfirmDialogOkText,\n removeAnnexConfirmDialogCancelText,\n path,\n setOpen,\n menuRef,\n}: AnnexesMenuItemProps) {\n const prefix = usePrefix();\n const store = useAnnexesContext();\n const formContext = useFormContext();\n const formIsDisabled = useFormIsDisabled();\n const formIsReadOnly = useFormIsReadOnly();\n const { confirm } = useAlertDialog();\n\n const deferredDisplayStatus = useAnnexState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const isRemovable = useAnnexState(\n path,\n (state) =>\n state != null && (state.schema.typeInfo.nullable || state.isRepetitive),\n );\n const title = useAnnexState(path, (state) => state?.title);\n const subtitle = useAnnexState(path, (state) => state?.subtitle);\n const nonRepetitiveDescription = useAnnexState(\n path,\n (state) => state && !state.isRepetitive && state.description,\n );\n\n const removeAnnex = async () => {\n const { getAnnexState, removeAnnex } = store.getState().actions;\n const state = getAnnexState(path);\n if (!state) {\n return;\n }\n\n if (\n !state.dirty ||\n (await confirm(\n // The form context will typically not be in the scope of the alert\n // dialog, so we need to provide it\n <FormContext.Provider value={{ ...formContext, currentPath: path }}>\n {removeAnnexConfirmDialogMessage?.(\n <strong>\n {state.title}\n {state.subtitle && <> — {state.subtitle}</>}\n </strong>,\n )}\n </FormContext.Provider>,\n {\n title: removeAnnexConfirmDialogTitle,\n color: \"danger\",\n okText: removeAnnexConfirmDialogOkText,\n cancelText: removeAnnexConfirmDialogCancelText,\n triggerElement: menuRef.current,\n },\n ))\n ) {\n void removeAnnex(state.path, state.isRepetitive);\n setOpen(false);\n }\n };\n\n const handleItemKeyDown = (evt: KeyboardEvent) => {\n if (\n isRemovable &&\n !formIsDisabled &&\n !formIsReadOnly &&\n evt.key === \"Delete\"\n ) {\n void removeAnnex();\n }\n };\n const handleRemoveButtonClick = (evt: MouseEvent) => {\n evt.stopPropagation();\n void removeAnnex();\n };\n\n return (\n <DropdownMenuRadioItem\n color=\"primary\"\n data-status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-accent={controlStatusToAccent(\n displayStatusToControlStatus(deferredDisplayStatus),\n )}\n showRadio={false}\n value={path.toString()}\n className={prefix(\"annexes__menu-annex\")}\n actionProps={{\n className: prefix(\"annexes__menu-annex-action\"),\n }}\n contentProps={{\n className: prefix(\"annexes__menu-annex-content\"),\n }}\n onKeyDown={handleItemKeyDown}\n >\n <CurrentPath path={path}>\n <div className={prefix(\"annexes__menu-annex-content-container\")}>\n <div className={prefix(\"annexes__menu-annex-title\")}>\n {title}\n {subtitle && (\n <span className={prefix(\"annexes__menu-annex-subtitle\")}>\n {subtitle}\n </span>\n )}\n </div>\n {nonRepetitiveDescription && (\n <div className={prefix(\"annexes__menu-annex-description\")}>\n {nonRepetitiveDescription}\n </div>\n )}\n </div>\n {isRemovable && !formIsReadOnly && (\n <>\n {removeAnnexKeyboardHint && (\n <VisuallyHidden>{removeAnnexKeyboardHint}</VisuallyHidden>\n )}\n <IconButton\n className={prefix(\"annexes__menu-annex-remove\")}\n icon={faTrash}\n label={removeAnnexButtonLabel ?? \"\"}\n color=\"danger\"\n circle\n disabled={formIsDisabled}\n onClick={handleRemoveButtonClick}\n aria-hidden=\"true\"\n />\n </>\n )}\n </CurrentPath>\n </DropdownMenuRadioItem>\n );\n}\n\n/** Properties of a new item in the annexes' menu. */\ninterface AnnexManagerNewItemProps {\n annex: ResolvedAnnexObject;\n}\n\n/** New item in the annexes' menu. */\nfunction AnnexesMenuNewItem({ annex }: AnnexManagerNewItemProps) {\n const prefix = usePrefix();\n const formIsDisabled = useFormIsDisabled();\n const formManager = useFormManager();\n const store = useAnnexesContext();\n\n const isRepetitive =\n annex.path.lastFragment === AbsolutePathFragment.Wildcard;\n const title = useStore(store, (state) =>\n isRepetitive\n ? (annex.title as ReactNode)\n : state.actions.getAnnexState(annex.path)?.title,\n );\n\n const canBeAdded = useStore(store, (state) => {\n let canBeAdded = false;\n if (isRepetitive) {\n const annexState = state.actions.getRepetitiveAnnexState(\n annex.path.parent(),\n );\n if (!annexState) {\n return false;\n }\n let maxSize = annexState.maxAnnexes;\n // Read max size from the schema restrictions if not defined\n if (maxSize == null) {\n const { restrictions } = annexState.schema.typeInfo;\n if (typeof restrictions.maxSize === \"number\") {\n maxSize = restrictions.maxSize;\n }\n }\n canBeAdded =\n maxSize == null ||\n (annexState.rowIds != null && annexState.rowIds.length < maxSize);\n } else {\n const annexState = state.actions.getAnnexState(annex.path);\n canBeAdded = annexState?.isNull ?? false;\n }\n return canBeAdded;\n });\n\n const [gettingValue, setGettingValue] = useState(false);\n const handleItemSelect = useCallback(async () => {\n const schema = formManager.schema(annex.path);\n const initialValue = schema.typeInfo.nullable\n ? nullableSchemaInnerSchema(schema).initialValue\n : schema.initialValue;\n\n let toAdd = initialValue;\n if (annex.getValue) {\n try {\n setGettingValue(true);\n toAdd = await annex.getValue(await schema.clone(initialValue));\n } finally {\n setGettingValue(false);\n }\n }\n\n if (toAdd == null) {\n return;\n }\n\n // Add new annex\n void store.getState().actions.addAnnex(annex.path, toAdd);\n }, [annex, formManager, store]);\n\n return (\n <DropdownMenuItem\n color=\"primary\"\n className={prefix(\"annexes__menu-new-annex\")}\n disabled={formIsDisabled || !canBeAdded || gettingValue}\n onSelect={handleItemSelect}\n contentProps={{\n className: prefix(\"annexes__menu-new-annex-content\"),\n }}\n >\n <CurrentPath path={isRepetitive ? annex.path.parent() : annex.path}>\n <div className={prefix(\"annexes__menu-new-annex-title\")}>{title}</div>\n {annex.description && (\n <div className={prefix(\"annexes__menu-new-annex-description\")}>\n {annex.description}\n </div>\n )}\n </CurrentPath>\n </DropdownMenuItem>\n );\n}\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport { boolDataAttr, Tab } from \"@ostack.tech/ui\";\nimport { useCallback, useRef } from \"react\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { visiblyFocus } from \"../../utils/useControlAutofocus.ts\";\nimport { useIssuesDisplayMode, useOnPathFocus } from \"../FormApp\";\nimport { useResetFocus } from \"../FormApp/FormAppContext.ts\";\nimport { IssueMessages } from \"../IssueMessages\";\nimport { IssuesPopover } from \"../IssuesPopover\";\nimport { useAnnexState } from \"./AnnexesContext.ts\";\n\nexport interface AnnexTabProps {\n path: AbsolutePath;\n}\n\nexport function AnnexTab({ path }: AnnexTabProps) {\n const prefix = usePrefix();\n const issuesDisplayMode = useIssuesDisplayMode();\n const deferredIssuesToDisplay = useAnnexState(\n path,\n useShallow(\n (state) =>\n (issuesDisplayMode === \"inline\" && state?.deferredIssuesToDisplay) ||\n [],\n ),\n );\n const deferredDisplayStatus = useAnnexState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const title = useAnnexState(path, (state) => state?.title);\n const subtitle = useAnnexState(path, (state) => state?.subtitle);\n\n const tabRef = useRef<HTMLButtonElement | null>(null);\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath: AbsolutePath) => {\n if (tabRef.current && path.equals(focusedPath)) {\n // In inline mode the issues popover should get focused instead\n if (issuesDisplayMode === \"panel\") {\n visiblyFocus(tabRef.current);\n }\n // Let the annex be opened before resetting focus\n setTimeout(() => resetFocus());\n }\n },\n [issuesDisplayMode, path, resetFocus],\n ),\n );\n\n return (\n <>\n <Tab\n className={prefix(\"annexes__tab\")}\n value={path.toString()}\n status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-has-issues={boolDataAttr(deferredIssuesToDisplay.length > 0)}\n tabInnerProps={{ className: prefix(\"annexes__tab-inner\") }}\n ref={tabRef}\n >\n <CurrentPath path={path}>\n <span className={prefix(\"annexes__tab-title\")}>{title}</span>\n {subtitle && (\n <span className={prefix(\"annexes__tab-subtitle\")}>{subtitle}</span>\n )}\n </CurrentPath>\n </Tab>\n\n {issuesDisplayMode === \"inline\" && (\n <IssuesPopover\n path={path}\n buttonContainerProps={{\n className: prefix(\"annexes__tab-issues-popover-button-container\"),\n }}\n iconButtonProps={{\n className: prefix(\"annexes__tab-issues-popover-button\"),\n }}\n >\n <IssueMessages issues={deferredIssuesToDisplay} />\n </IssuesPopover>\n )}\n </>\n );\n}\n","import { cx, TabList, useMediaBreakpointUp } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useAnnexesContext } from \"./AnnexesContext.ts\";\nimport { AnnexTab } from \"./AnnexTab.tsx\";\n\n/** Properties of the annex tab list component. */\nexport interface AnnexTabListProps extends ComponentPropsWithoutRef<\n typeof TabList\n> {\n hideNonActiveOnSmallScreens: boolean;\n}\n\n/** List of annex tabs. */\nexport const AnnexesTabList = forwardRef<\n ComponentRef<typeof TabList>,\n AnnexTabListProps\n>(function AnnexManager(\n { hideNonActiveOnSmallScreens, rootProps, className, ...otherProps },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const store = useAnnexesContext();\n const activeAnnex = useStore(store, (state) => state.activeAnnex);\n const tabStates = useStore(\n store,\n useShallow((state) => state.tabStates()),\n );\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n\n return (\n <TabList\n className={cx(prefix(\"annexes__tab-list\"), className)}\n {...otherProps}\n rootProps={{\n ...rootProps,\n className: cx(prefix(\"annexes__tab-list-root\"), rootProps?.className),\n }}\n ref={forwardedRef}\n >\n {tabStates.map((state) =>\n !hideNonActiveOnSmallScreens ||\n isLargeScreen ||\n state.path.equals(activeAnnex) ? (\n <AnnexTab key={state.path.toString()} {...state} />\n ) : null,\n )}\n </TabList>\n );\n});\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { useFormManager } from \"@ostack.tech/kform-react\";\nimport {\n type Button,\n cx,\n type DropdownMenu,\n type DropdownMenuContent,\n FeedbackList,\n type TabList,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useIssuesDisplayMode } from \"../FormApp\";\nimport { IssueMessages } from \"../IssueMessages\";\nimport { IssuesPopover } from \"../IssuesPopover\";\nimport {\n type AnnexState,\n type RepetitiveAnnexState,\n useAnnexesContext,\n} from \"./AnnexesContext.ts\";\nimport { AnnexesMenu } from \"./AnnexesMenu.tsx\";\nimport { AnnexesTabList } from \"./AnnexesTabList.tsx\";\n\n/** Properties of the annexes' manager component. */\nexport interface AnnexesManagerProps extends ComponentPropsWithoutRef<\"nav\"> {\n /** Text of the menu button. */\n menuButtonText?: ReactNode;\n /** Text of the \"add annex\" item. */\n addAnnexText?: ReactNode;\n /** Label of the remove annex button, announced by assistive technologies. */\n removeAnnexButtonLabel?: string;\n /**\n * Hint on how to remove an annex via keyboard, announced by assistive\n * technologies.\n */\n removeAnnexKeyboardHint?: string;\n /** Title of the \"remove annex\" confirm dialog. */\n removeAnnexConfirmDialogTitle?: ReactNode;\n /**\n * Function that should return the message of the \"remove annex\" confirm\n * dialog, given a node with the name of the annex.\n *\n * @param annexName Node containing the name of the annex.\n */\n removeAnnexConfirmDialogMessage?: (annexName: ReactNode) => ReactNode;\n /** Text of the \"remove annex\" confirm dialog OK button. */\n removeAnnexConfirmDialogOkText?: ReactNode;\n /** Text of the \"remove annex\" confirm dialog cancel button. */\n removeAnnexConfirmDialogCancelText?: ReactNode;\n /** Properties to pass to the menu container element. */\n menuContainerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the menu trigger component. */\n menuTriggerProps?: Omit<ComponentPropsWithRef<typeof Button>, \"icon\">;\n /** Properties to pass to the menu content component. */\n menuContentProps?: ComponentPropsWithRef<typeof DropdownMenuContent>;\n /** Properties to pass to the menu component. */\n menuProps?: ComponentPropsWithRef<typeof DropdownMenu>;\n /** Properties to pass to the tab-list container element. */\n tabListContainerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the tab-list component. */\n tabListProps?: ComponentPropsWithRef<typeof TabList>;\n}\n\n/**\n * Component used to manage the form's annexes. Provides a menu that allows\n * changing, adding, and removing annexes, as well as a list of tabs for each\n * existing annex.\n */\nexport const AnnexesManager = forwardRef<\n ComponentRef<\"nav\">,\n AnnexesManagerProps\n>(function AnnexManager(\n {\n menuButtonText,\n addAnnexText,\n removeAnnexButtonLabel,\n removeAnnexKeyboardHint,\n removeAnnexConfirmDialogTitle,\n removeAnnexConfirmDialogMessage,\n removeAnnexConfirmDialogOkText,\n removeAnnexConfirmDialogCancelText,\n className,\n \"aria-label\": ariaLabel,\n menuContainerProps,\n menuTriggerProps,\n menuContentProps,\n menuProps,\n tabListContainerProps,\n tabListProps,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n ariaLabel ??= locale.AnnexesManager[\"aria-label\"];\n menuButtonText ??= locale.AnnexesManager.menuButtonText;\n addAnnexText ??= locale.AnnexesManager.addAnnexText;\n removeAnnexButtonLabel ??= locale.AnnexesManager.removeAnnexButtonLabel;\n removeAnnexKeyboardHint ??= locale.AnnexesManager.removeAnnexKeyboardHint;\n removeAnnexConfirmDialogTitle ??=\n locale.AnnexesManager.removeAnnexConfirmDialogTitle;\n removeAnnexConfirmDialogMessage ??=\n locale.AnnexesManager.removeAnnexConfirmDialogMessage;\n removeAnnexConfirmDialogOkText ??=\n locale.AnnexesManager.removeAnnexConfirmDialogOkText;\n removeAnnexConfirmDialogCancelText ??=\n locale.AnnexesManager.removeAnnexConfirmDialogCancelText;\n const store = useAnnexesContext();\n const issuesDisplayMode = useIssuesDisplayMode();\n const tablessStates: (AnnexState | RepetitiveAnnexState)[] = useStore(\n store,\n useShallow((state) =>\n issuesDisplayMode === \"inline\" ? state.tablessStates() : [],\n ),\n );\n const tablessPaths = useMemo(\n () => tablessStates.map((state) => state.path),\n [tablessStates],\n );\n const deferredTablessIssuesToDisplay = useMemo(\n () => tablessStates.map((state) => state.deferredIssuesToDisplay || []),\n [tablessStates],\n );\n const formManager = useFormManager();\n const shouldRenderMenu = useStore(store, (state) =>\n state.annexes.some(\n (annex) =>\n annex.path.lastFragment === AbsolutePathFragment.Wildcard ||\n formManager.schema(annex.path).typeInfo.nullable,\n ),\n );\n\n return (\n <nav\n className={cx(prefix(\"annexes__manager\"), className)}\n aria-label={ariaLabel}\n {...otherProps}\n ref={forwardedRef}\n >\n {shouldRenderMenu && (\n <div\n {...menuContainerProps}\n className={cx(\n prefix(\"annexes__menu-container\"),\n menuContainerProps?.className,\n )}\n >\n <AnnexesMenu\n menuButtonText={menuButtonText}\n addAnnexText={addAnnexText}\n removeAnnexButtonLabel={removeAnnexButtonLabel}\n removeAnnexKeyboardHint={removeAnnexKeyboardHint}\n removeAnnexConfirmDialogTitle={removeAnnexConfirmDialogTitle}\n removeAnnexConfirmDialogMessage={removeAnnexConfirmDialogMessage}\n removeAnnexConfirmDialogOkText={removeAnnexConfirmDialogOkText}\n removeAnnexConfirmDialogCancelText={\n removeAnnexConfirmDialogCancelText\n }\n {...menuProps}\n menuTriggerProps={menuTriggerProps}\n menuContentProps={menuContentProps}\n />\n </div>\n )}\n\n {shouldRenderMenu && issuesDisplayMode === \"inline\" && (\n <IssuesPopover\n buttonContainerProps={{\n className: prefix(\"annexes__issues-popover-container\"),\n }}\n relevantPaths={tablessPaths}\n >\n <FeedbackList>\n {tablessStates.map((state, i) => (\n <IssueMessages\n key={state.path.toString()}\n path={state.path}\n issues={deferredTablessIssuesToDisplay[i] ?? []}\n unwrapped\n />\n ))}\n </FeedbackList>\n </IssuesPopover>\n )}\n\n <div\n {...tabListContainerProps}\n className={cx(\n prefix(\"annexes__tab-list-container\"),\n tabListContainerProps?.className,\n )}\n >\n <AnnexesTabList\n hideNonActiveOnSmallScreens={shouldRenderMenu}\n {...tabListProps}\n />\n </div>\n </nav>\n );\n});\n","import type { SealedValidationIssue } from \"@ostack.tech/kform\";\nimport { FeedbackList, useIsInTableCell } from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { useIssuesDisplayMode } from \"../components/FormApp\";\nimport {\n IssueMessages,\n type IssueMessagesByCode,\n} from \"../components/IssueMessages\";\nimport { IssuesPopover } from \"../components/IssuesPopover\";\n\n/** Options of the `useControlIssues` hook. */\nexport interface UseControlIssuesOptions {\n /** Mapping from path to issues to display. */\n issuesToDisplay: Record<string, SealedValidationIssue[]>;\n /** Mapping from path to issue messages by code. */\n issueMessages?: Record<string, IssueMessagesByCode | undefined>;\n /** Whether issues should be displayed. */\n displayIssues?: boolean;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Hook which helps a control component render its issues.\n *\n * This hook returns a pair containing two React nodes:\n *\n * - The first element of the pair contains the node that should be rendered when\n * the issues are to appear inline. This will be `null` if the issues should\n * not appear inline.\n * - The second element of the pair contains the node that should be rendered when\n * the issues are to appear within a popover. This will be `null` if the\n * issues should not appear in a popover.\n */\nexport function useControlIssues({\n issuesToDisplay,\n issueMessages,\n displayIssues = true,\n issueMessagesProps,\n}: UseControlIssuesOptions): [ReactNode, ReactNode] {\n const issuesDisplayMode = useIssuesDisplayMode();\n const isInTableCell = useIsInTableCell();\n\n const {\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n ...feedbackListProps\n } = issueMessagesProps ?? {};\n const issuesNode = displayIssues && (\n <FeedbackList {...feedbackListProps} hidden={issuesDisplayMode === \"panel\"}>\n {Object.entries(issuesToDisplay).map(([path, issues], i) => (\n <IssueMessages\n key={i}\n path={path}\n issues={issues}\n messages={issueMessages?.[path]}\n displayIssueCodes={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n unwrapped\n />\n ))}\n </FeedbackList>\n );\n if (issuesDisplayMode === \"panel\") {\n return [issuesNode, null];\n }\n return [\n isInTableCell ? null : issuesNode,\n isInTableCell ? <IssuesPopover>{issuesNode}</IssuesPopover> : null,\n ];\n}\n","import type {\n AbsolutePath,\n DisplayStatus,\n SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport {\n useDataTableColumnLabel,\n useOnFieldLabelChange,\n usePrinting,\n useStartPrintingTask,\n} from \"@ostack.tech/ui\";\nimport {\n type FocusEvent,\n type ReactNode,\n type Ref,\n type RefObject,\n useCallback,\n useDeferredValue,\n useEffect,\n useImperativeHandle,\n useMemo,\n} from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useRegisterControllerWithinControlField } from \"../components/ControlField\";\nimport {\n useFormIsDisabled,\n useFormIsReadOnly,\n useRegisterController,\n useRegisterLabel,\n} from \"../components/FormApp\";\nimport {\n useFormAppContext,\n useSetLatestInteraction,\n} from \"../components/FormApp/FormAppContext.ts\";\nimport { useControlAutofocus } from \"./useControlAutofocus.ts\";\n\n/** Options when registering the control. */\nexport interface UseRegisterControlOptions<T> {\n controller: Controller<T>;\n issuesPanelLabel?: ReactNode;\n ariaLabel?: string;\n issuesPanelLabelSuffix?: ReactNode;\n preventAutoFocus?: boolean;\n apiRef?: Ref<Controller<T> | undefined>;\n}\n\n/** Result of registering the control. */\nexport interface UseRegisterControlResult<TElem> {\n displayLoading: boolean;\n displayDisabled: boolean;\n displayReadOnly: boolean;\n displayStatusToDisplay: DisplayStatus | undefined;\n issuesToDisplay: SealedValidationIssue[];\n autofocusRef: RefObject<TElem | null>;\n handleFocus: (event: FocusEvent) => void;\n}\n\n/** Hook used to register a control within the form app. */\nexport function useRegisterControl<T, TElem extends HTMLElement = HTMLElement>({\n controller,\n issuesPanelLabel,\n ariaLabel,\n issuesPanelLabelSuffix,\n preventAutoFocus,\n apiRef,\n}: UseRegisterControlOptions<T>): UseRegisterControlResult<TElem> {\n const printing = usePrinting();\n const { useState, usePath, useInitialized, useDisplayStatus } = controller;\n const path = usePath();\n const formIsDisabled = useFormIsDisabled();\n const displayDisabled =\n useState((state) => !state.initialized || !state.exists) || formIsDisabled;\n const displayReadOnly = useFormIsReadOnly();\n const deferredIsValidating = useDeferredValue(\n useState((state) => state.validationStatus === \"validating\"),\n );\n const initialized = useInitialized();\n const displayLoading = !initialized || deferredIsValidating;\n const displayStatusToDisplay = useDeferredValue(useDisplayStatus());\n const issuesToDisplay = useDeferredValue(\n useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n\n // Start a printing task until the control is initialised\n const finishPrintingTask = useStartPrintingTask();\n useEffect(() => {\n if (initialized) {\n finishPrintingTask();\n }\n }, [finishPrintingTask, initialized]);\n\n // Register the issues panel label\n const columnLabel = useDataTableColumnLabel();\n useRegisterLabel(\n path,\n issuesPanelLabel || columnLabel || ariaLabel,\n issuesPanelLabel ? 1 : -1,\n );\n useRegisterFieldLabel(path, issuesPanelLabelSuffix);\n\n // Register the controller within its control field\n useRegisterControllerWithinControlField(controller, issuesToDisplay);\n\n // Register the controller in the form app\n useRegisterController(controller);\n\n // Expose the control's API via `apiRef`\n useImperativeHandle(apiRef, () => controller, [controller]);\n\n // Autofocus control when the active path changes\n const autofocusRef = useControlAutofocus<T, TElem>(\n controller,\n !preventAutoFocus && !printing,\n );\n\n // Handle control focus\n const setLatestInteraction = useSetLatestInteraction();\n const handleFocus = useCallback(\n (event: FocusEvent) => {\n if (\n !printing &&\n event.target === event.currentTarget &&\n !event.defaultPrevented\n ) {\n setLatestInteraction(controller.getState().path);\n }\n },\n [controller, printing, setLatestInteraction],\n );\n\n return useMemo(\n () => ({\n displayLoading: printing ? false : displayLoading,\n displayDisabled: printing ? false : displayDisabled,\n displayReadOnly: printing ? false : displayReadOnly,\n displayStatusToDisplay: printing ? undefined : displayStatusToDisplay,\n issuesToDisplay: printing ? [] : issuesToDisplay,\n autofocusRef,\n handleFocus,\n }),\n [\n autofocusRef,\n displayDisabled,\n displayLoading,\n displayReadOnly,\n displayStatusToDisplay,\n handleFocus,\n issuesToDisplay,\n printing,\n ],\n );\n}\n\n/** Hook used to register a label for all control field's controls. */\nfunction useRegisterFieldLabel(\n path: AbsolutePath,\n issuesPanelLabelSuffix?: ReactNode,\n) {\n const { store: formAppStore } = useFormAppContext();\n useOnFieldLabelChange(\n useCallback(\n (label) =>\n formAppStore.getState().actions.registerLabel(\n path,\n label && issuesPanelLabelSuffix ? (\n <>\n {label}\n {issuesPanelLabelSuffix}\n </>\n ) : (\n label\n ),\n ),\n [formAppStore, issuesPanelLabelSuffix, path],\n ),\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n InvalidPathError,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n Checkbox,\n type CheckboxChecked,\n combineEventHandlers,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type Dispatch,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the checkbox control component. */\nexport interface CheckboxControlProps<T extends boolean | null = boolean | null>\n extends\n Omit<\n InputOptions<T, CheckboxChecked, ComponentRef<typeof Checkbox>>,\n \"enabled\" | \"format\" | \"parse\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Checkbox>,\n \"defaultChecked\" | \"checked\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | InputController<T, CheckboxChecked, ComponentRef<typeof Checkbox>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Checkbox control component supporting (possibly nullable) schemas of type\n * \"Boolean\". `null` values are represented as an \"indeterminate\" checkbox.\n */\nexport const CheckboxControl = forwardRef(function CheckboxControl<\n T extends boolean | null = boolean | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n onFocus,\n onCheckedChange,\n onBlurToOutside,\n ...otherProps\n }: CheckboxControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Checkbox>>,\n) {\n const [formattedValue, setFormattedValue] = useState<CheckboxChecked>(false);\n const controller = useInput<\n T,\n CheckboxChecked,\n ComponentRef<typeof Checkbox>\n >(path, {\n enabled: !useFormIsLoading(),\n parse: parseCheckboxValue,\n format: formatToCheckboxValue,\n setFormattedValue,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLButtonElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n if (schema.typeInfo.name !== \"Boolean\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n \"booleans, but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedCheckboxRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Checkbox\n checked={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n onCheckedChange={combineEventHandlers(\n onCheckedChange,\n combineEventHandlers(\n inputProps.onChange,\n setFormattedValue as Dispatch<CheckboxChecked>,\n ),\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedCheckboxRef}\n />\n {inlineIssues}\n {popoverIssues}\n </>\n );\n});\n\n/** Parses a checkbox control formatted value. */\nfunction parseCheckboxValue<T extends boolean | null>(\n formattedValue: CheckboxChecked,\n state: FormatterControllerState<T, CheckboxChecked>,\n): T {\n return (\n formattedValue === \"indeterminate\"\n ? state.schema.typeInfo.nullable\n ? null\n : state.schema.initialValue\n : formattedValue\n ) as T;\n}\n\n/** Formats a checkbox control value. */\nfunction formatToCheckboxValue<T extends boolean | null>(\n value: T | undefined,\n): CheckboxChecked {\n return value === undefined ? false : (value ?? \"indeterminate\");\n}\n","import type { Schema } from \"@ostack.tech/kform\";\nimport { equals, type Listable } from \"@ostack.tech/kform-react\";\nimport { Option, OptionsGroup } from \"@ostack.tech/ui\";\nimport type { JSX } from \"react\";\n\nimport type { OptionObject, OptionsGroupObject } from \"./options.ts\";\n\n/**\n * Parses a selection value from the (string) index of an option (or empty\n * string).\n */\nexport function parseSelectionValueFromOptionIndex<T>(\n formattedValue: string,\n schema: Schema<T>,\n options: { value: T }[],\n): T {\n if (formattedValue === \"\") {\n return schema.typeInfo.nullable ? (null as T) : schema.initialValue;\n }\n return options[+formattedValue].value;\n}\n\n/**\n * Formats a selection value as the (string) index of an option (or empty\n * string).\n */\nexport function formatSelectionValueAsOptionIndex<T>(\n value: T | undefined,\n options: { value: T }[],\n): string {\n const idx = options.findIndex((option) => equals(option.value, value));\n return idx === -1 ? \"\" : idx.toString();\n}\n\n/** Parses an array of selection values from an array of (string) option indices. */\nexport function parseSelectionValuesFromOptionIndices<\n T,\n TListable extends Listable<T> | null,\n>(\n formattedValue: string[],\n schema: Schema<TListable>,\n options: { value: T }[],\n): T[] | null {\n if (formattedValue.length === 0) {\n return schema.typeInfo.nullable ? null : [];\n }\n return formattedValue.map((idx) => options[+idx].value);\n}\n\n/** Formats an array of selection values as an array of (string) option indices. */\nexport function formatSelectionValuesAsOptionIndices<T>(\n arrayValue: T[] | null | undefined,\n options: { value: T }[],\n): string[] {\n return (\n arrayValue?.map((v) => {\n const idx = options.findIndex((option) => equals(option.value, v));\n return idx === -1 ? \"\" : idx.toString();\n }) ?? []\n );\n}\n\n/**\n * Transforms option objects into React nodes.\n *\n * @param options Option objects.\n * @returns React nodes representing the objects.\n */\nexport function optionObjectsToNodes<T>(\n options: (OptionsGroupObject<T> | OptionObject<T>)[],\n): JSX.Element[] {\n let optionIndex = 0;\n return options.map(({ key, ...optionOrGroup }, i) =>\n \"options\" in optionOrGroup ? (\n <OptionsGroup key={key ?? i} {...optionOrGroup}>\n {optionOrGroup.options.map(\n ({ key, value, text, ...optionProps }, i) => (\n <Option key={key ?? i} value={optionIndex++} {...optionProps}>\n {text ?? value?.toString() ?? \"\"}\n </Option>\n ),\n )}\n </OptionsGroup>\n ) : (\n <Option key={key ?? i} {...optionOrGroup} value={optionIndex++}>\n {optionOrGroup.text ?? optionOrGroup.value?.toString() ?? \"\"}\n </Option>\n ),\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Listable,\n type ListableInputController,\n type ListableInputOptions,\n useListableInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n Checkbox,\n CheckboxGroup,\n combineEventHandlers,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type Key,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport {\n formatSelectionValuesAsOptionIndices,\n parseSelectionValuesFromOptionIndices,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Checkbox in object notation. */\nexport type CheckboxObject<T = unknown> = Omit<\n ComponentPropsWithRef<typeof Checkbox>,\n \"defaultChecked\" | \"checked\" | \"value\" | \"children\"\n> & {\n /** Option value. */\n value: T;\n /** Option's rendered text. */\n text?: ReactNode;\n /** Option's unique key. */\n key?: Key;\n};\n\n/** Properties of the checkbox group control component. */\nexport interface CheckboxGroupControlProps<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n>\n extends\n Omit<\n ListableInputOptions<\n T,\n TListable,\n string[],\n ComponentRef<typeof CheckboxGroup>\n >,\n \"enabled\" | \"formatFromArray\" | \"parseToArray\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof CheckboxGroup>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"children\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /** Checkbox group control options. */\n options: CheckboxObject<T>[];\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | ListableInputController<\n T,\n TListable,\n string[],\n ComponentRef<typeof CheckboxGroup>\n >\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Checkbox group control component supporting (possibly nullable) listable\n * schemas with elements of any type.\n *\n * If the schema is nullable, this component sets the form value to `null` when\n * the control contains no elements. Note, however, that the form may still hold\n * an empty listable as value if set programmatically.\n */\nexport const CheckboxGroupControl = forwardRef(function CheckboxGroupControl<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n>(\n {\n path,\n options,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: CheckboxGroupControlProps<T, TListable>,\n forwardedRef: ForwardedRef<ComponentRef<typeof CheckboxGroup>>,\n) {\n const [arrayValue, setArrayValue] = useState<T[] | null>(null);\n const formattedValue = useMemo(\n () => formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options, arrayValue],\n );\n const controller = useListableInput<\n T,\n TListable,\n string[],\n ComponentRef<typeof CheckboxGroup>\n >(path, {\n enabled: !useFormIsLoading(),\n parseToArray: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n formatFromArray: useCallback(\n (arrayValue: T[] | null) =>\n formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { getState, useSchema, usePath, inputProps } = controller;\n const { restrictions } = useSchema().typeInfo;\n const absolutePath = usePath();\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<TListable, HTMLDivElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string[]) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n getState().schema,\n options,\n ),\n ),\n [getState, options],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedCheckboxGroupRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <CheckboxGroup\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedCheckboxGroupRef}\n >\n {options.map(({ value, text, key, ...checkboxProps }, i) => (\n <Checkbox key={key ?? i} value={i} {...checkboxProps}>\n {text ?? value?.toString() ?? \"\"}\n </Checkbox>\n ))}\n </CheckboxGroup>\n {inlineIssues}\n {popoverIssues}\n </>\n );\n});\n","import type { Schema } from \"@ostack.tech/kform\";\nimport {\n formatTemporalAsString,\n type Temporal,\n} from \"@ostack.tech/kform-react\";\nimport { addDays, max, min, parseISO } from \"date-fns\";\n\n/** Returns the minimum date allowed based on a temporal schema's restrictions. */\nexport function minDateRestriction<T extends Temporal | null>(\n schema: Schema<T>,\n): Date | undefined {\n const { restrictions } = schema.typeInfo;\n const min = temporalRestrictionToDate(restrictions.min, schema);\n const exclusiveMin = temporalRestrictionToDate(\n restrictions.exclusiveMin,\n schema,\n );\n const minFromMinExclusive = exclusiveMin && addDays(exclusiveMin, 1);\n return min != null && minFromMinExclusive != null\n ? max([min, minFromMinExclusive])\n : (min ?? minFromMinExclusive);\n}\n\n/** Returns the maximum date allowed based on a temporal schema's restrictions. */\nexport function maxDateRestriction<T extends Temporal | null>(\n schema: Schema<T>,\n): Date | undefined {\n const { restrictions } = schema.typeInfo;\n const max = temporalRestrictionToDate(restrictions.max, schema);\n const exclusiveMax = temporalRestrictionToDate(\n restrictions.exclusiveMax,\n schema,\n );\n const maxFromMaxExclusive = exclusiveMax && addDays(exclusiveMax, -1);\n return max != null && maxFromMaxExclusive != null\n ? min([max, maxFromMaxExclusive])\n : (max ?? maxFromMaxExclusive);\n}\n\n/** Transforms a temporal restriction in a JS date. */\nfunction temporalRestrictionToDate<T extends Temporal | null>(\n restriction: unknown,\n schema: Schema<T>,\n) {\n return restriction == null\n ? undefined\n : parseISO(formatTemporalAsString(restriction as T, schema));\n}\n","import type { Schema } from \"@ostack.tech/kform\";\nimport type { Temporal } from \"@ostack.tech/kform-react\";\nimport {\n type DateFormatterOptions,\n type DateParserOptions,\n type DateTransformerOptions,\n useDateTransformer,\n} from \"@ostack.tech/ui\";\nimport { format as fnsFormat, parseISO } from \"date-fns\";\nimport { useMemo } from \"react\";\n\n/** Temporal string transformer. */\nexport interface TemporalStringTransformer {\n /**\n * Function used to parse a formatted date as exposed by a date input as a\n * temporal string.\n */\n parse: <T extends Temporal | null = Temporal | null>(\n formattedDate: string,\n schema: Schema<T>,\n options?: DateParserOptions,\n ) => string;\n /**\n * Function used to format a temporal string as a string accepted by a date\n * input.\n */\n format: <T extends Temporal | null = Temporal | null>(\n temporalString: string,\n schema: Schema<T>,\n options?: DateFormatterOptions,\n ) => string;\n}\n\n/**\n * Hook exposing functions to transform a temporal string value from/into a\n * string representation of a date accepted by a date input.\n */\nexport function useTemporalStringTransformer(\n dateTransformerOptions?: DateTransformerOptions,\n): TemporalStringTransformer {\n const { format, parse } = useDateTransformer(dateTransformerOptions);\n\n return useMemo(\n () => ({\n parse: <T extends Temporal | null = Temporal | null>(\n formattedDate: string,\n schema: Schema<T>,\n options?: DateParserOptions,\n ) => {\n const date = parse(formattedDate, options);\n if (date === null) {\n return \"\";\n }\n\n const dateString = fnsFormat(date, \"yyyy-MM-dd\");\n switch (schema.typeInfo.name) {\n case \"Instant\":\n return `${dateString}T00:00:00.000Z`;\n case \"LocalDateTime\":\n return `${dateString}T00:00:00`;\n default: // `LocalDate` or JavaScript `Date`\n return dateString;\n }\n },\n format: <T extends Temporal | null = Temporal | null>(\n temporalString: string,\n _schema: Schema<T>,\n options?: DateFormatterOptions,\n ) => temporalString && format(parseISO(temporalString), options),\n }),\n [format, parse],\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Temporal,\n type TemporalInputController,\n type TemporalInputOptions,\n useTemporalInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n DateInput,\n type DateValueRepresentations,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useState,\n} from \"react\";\n\nimport {\n maxDateRestriction,\n minDateRestriction,\n} from \"../../utils/dateRestrictions.ts\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport { useTemporalStringTransformer } from \"../../utils/useTemporalStringTransformer.ts\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the date control component. */\nexport interface DateControlProps<T extends Temporal | null = Temporal | null>\n extends\n Omit<\n TemporalInputOptions<T, string, ComponentRef<typeof DateInput>>,\n \"enabled\" | \"formatFromString\" | \"parseToString\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof DateInput>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | TemporalInputController<T, string, ComponentRef<typeof DateInput>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Date control component supporting nullable temporal schemas. */\nexport const DateControl = forwardRef(function DateControl<\n T extends Temporal | null = Temporal | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n required,\n minDate,\n maxDate,\n loading,\n disabled,\n readOnly,\n onFocus,\n onBlurToOutside,\n endAdornment,\n ...otherProps\n }: DateControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof DateInput>>,\n) {\n const { format, parse } = useTemporalStringTransformer({\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n });\n\n const [formattedValue, setFormattedValue] = useState(\"\");\n const controller = useTemporalInput<\n T,\n string,\n ComponentRef<typeof DateInput>\n >(path, {\n enabled: !useFormIsLoading(),\n parseToString: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n parse(formattedValue, state.schema),\n [parse],\n ),\n formatFromString: useCallback(\n (temporalString: string, state: FormatterControllerState<T, string>) =>\n format(temporalString, state.schema),\n [format],\n ),\n setFormattedValue,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLInputElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n ({ formattedValue }: DateValueRepresentations) => {\n setFormattedValue(formattedValue);\n inputProps.onChange(formattedValue);\n },\n [inputProps],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedDateInputRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <DateInput\n value={formattedValue}\n name={inputProps.name}\n locale={dateFnsLocale}\n shortFormat={shortFormat}\n fullFormat={fullFormat}\n required={required ?? restrictions.required === true}\n minDate={minDate ?? minDateRestriction(schema)}\n maxDate={maxDate ?? maxDateRestriction(schema)}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={handleValueChange}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedDateInputRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Temporal,\n type TemporalInputController,\n type TemporalInputOptions,\n useTemporalInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n DateRangeInput,\n type DateRangeValueRepresentations,\n type StringRange,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport {\n maxDateRestriction,\n minDateRestriction,\n} from \"../../utils/dateRestrictions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport { useTemporalStringTransformer } from \"../../utils/useTemporalStringTransformer.ts\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the date-range control component. */\nexport interface DateRangeControlProps<\n TStart extends Temporal | null = Temporal | null,\n TEnd extends Temporal | null = TStart,\n> extends Omit<\n ComponentPropsWithoutRef<typeof DateRangeInput>,\n \"defaultValue\" | \"value\"\n> {\n /** Path to the start value. */\n startPath: string | Path;\n /** Path to the end value. */\n endPath: string | Path;\n /**\n * Issue messages of this control's start.\n *\n * Mapping from an issue's code to its message.\n */\n startIssueMessages?: IssueMessagesByCode;\n /**\n * Issue messages of this control's end.\n *\n * Mapping from an issue's code to its message.\n */\n endIssueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Label suffix to use in the issues panel when displaying issues associated\n * with this field's start date.\n */\n issuesPanelStartLabelSuffix?: ReactNode;\n /**\n * Label suffix to use in the issues panel when displaying issues associated\n * with this field's end date.\n */\n issuesPanelEndLabelSuffix?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the start control's API. */\n startApiRef?: Ref<TemporalInputController<TStart, string> | undefined>;\n /** Reference to the end control's API. */\n endApiRef?: Ref<TemporalInputController<TEnd, string> | undefined>;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n onStartInitialized?: TemporalInputOptions<TStart, string>[\"onInitialized\"];\n onStartFormManagerEvent?: TemporalInputOptions<\n TStart,\n string\n >[\"onFormManagerEvent\"];\n onStartValueChange?: TemporalInputOptions<TStart, string>[\"onValueChange\"];\n onStartValidationStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onValidationStatusChange\"];\n onStartDisplayStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onDisplayStatusChange\"];\n onStartDirtyStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onDirtyStatusChange\"];\n onStartTouchedStatusChange?: TemporalInputOptions<\n TStart,\n string\n >[\"onTouchedStatusChange\"];\n onEndInitialized?: TemporalInputOptions<TEnd, string>[\"onInitialized\"];\n onEndFormManagerEvent?: TemporalInputOptions<\n TEnd,\n string\n >[\"onFormManagerEvent\"];\n onEndValueChange?: TemporalInputOptions<TEnd, string>[\"onValueChange\"];\n onEndValidationStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onValidationStatusChange\"];\n onEndDisplayStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onDisplayStatusChange\"];\n onEndDirtyStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onDirtyStatusChange\"];\n onEndTouchedStatusChange?: TemporalInputOptions<\n TEnd,\n string\n >[\"onTouchedStatusChange\"];\n}\n\n/** Date-range control component supporting nullable temporal schemas. */\nexport const DateRangeControl = forwardRef(function DateRangeControl<\n TStart extends Temporal | null = Temporal | null,\n TEnd extends Temporal | null = TStart,\n>(\n {\n startPath,\n endPath,\n startIssueMessages,\n endIssueMessages,\n issuesPanelLabel,\n issuesPanelStartLabelSuffix,\n issuesPanelEndLabelSuffix,\n displayIssues = true,\n preventAutoFocus,\n startApiRef,\n endApiRef,\n issueMessagesProps,\n required,\n minDate,\n maxDate,\n startLoading,\n endLoading,\n disabled,\n readOnly,\n startInputProps,\n endInputProps,\n onStartInitialized,\n onStartFormManagerEvent,\n onStartValueChange,\n onStartValidationStatusChange,\n onStartDisplayStatusChange,\n onStartDirtyStatusChange,\n onStartTouchedStatusChange,\n onEndInitialized,\n onEndFormManagerEvent,\n onEndValueChange,\n onEndValidationStatusChange,\n onEndDisplayStatusChange,\n onEndDirtyStatusChange,\n onEndTouchedStatusChange,\n onValueChange,\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n onBlurToOutside,\n endAdornment,\n ...otherProps\n }: DateRangeControlProps<TStart, TEnd>,\n forwardedRef: ForwardedRef<ComponentRef<typeof DateRangeInput>>,\n) {\n const [locale] = useLocale();\n issuesPanelStartLabelSuffix ??=\n locale.DateRangeControl.issuesPanelStartLabelSuffix;\n issuesPanelEndLabelSuffix ??=\n locale.DateRangeControl.issuesPanelEndLabelSuffix;\n\n const { format, parse } = useTemporalStringTransformer({\n locale: dateFnsLocale,\n shortFormat,\n fullFormat,\n });\n\n const [formattedValue, setFormattedValue] = useState<StringRange>({\n start: \"\",\n end: \"\",\n });\n const parseToString = useCallback(\n (\n formattedValue: string,\n state: FormatterControllerState<TStart | TEnd, string>,\n ) => parse(formattedValue, state.schema),\n [parse],\n );\n const formatFromString = useCallback(\n (\n stringValue: string,\n state: FormatterControllerState<TStart | TEnd, string>,\n ) => format(stringValue, state.schema),\n [format],\n );\n const formIsLoading = useFormIsLoading();\n const startController = useTemporalInput<TStart, string>(startPath, {\n enabled: !formIsLoading,\n parseToString,\n formatFromString,\n setFormattedValue: useCallback(\n (formattedValue: string) =>\n setFormattedValue(({ end }) => ({ start: formattedValue, end })),\n [],\n ),\n onInitialized: onStartInitialized,\n onFormManagerEvent: onStartFormManagerEvent,\n onValueChange: onStartValueChange,\n onValidationStatusChange: onStartValidationStatusChange,\n onDisplayStatusChange: onStartDisplayStatusChange,\n onDirtyStatusChange: onStartDirtyStatusChange,\n onTouchedStatusChange: onStartTouchedStatusChange,\n });\n const endController = useTemporalInput<TEnd, string, HTMLInputElement>(\n endPath,\n {\n enabled: !formIsLoading,\n parseToString,\n formatFromString,\n setFormattedValue: useCallback(\n (formattedValue: string) =>\n setFormattedValue(({ start }) => ({ start, end: formattedValue })),\n [],\n ),\n onInitialized: onEndInitialized,\n onFormManagerEvent: onEndFormManagerEvent,\n onValueChange: onEndValueChange,\n onValidationStatusChange: onEndValidationStatusChange,\n onDisplayStatusChange: onEndDisplayStatusChange,\n onDirtyStatusChange: onEndDirtyStatusChange,\n onTouchedStatusChange: onEndTouchedStatusChange,\n },\n );\n const { inputProps: startControllerInputProps } = startController;\n const startSchema = startController.useSchema();\n const startAbsolutePath = startController.usePath();\n const { restrictions: startRestrictions } = startSchema.typeInfo;\n const { inputProps: endControllerInputProps } = endController;\n const endSchema = endController.useSchema();\n const endAbsolutePath = endController.usePath();\n const { restrictions: endRestrictions } = endSchema.typeInfo;\n\n // Register the start control\n const {\n displayLoading: displayStartLoading,\n displayDisabled: displayStartDisabled,\n displayReadOnly: displayStartReadOnly,\n displayStatusToDisplay: startDisplayStatusToDisplay,\n issuesToDisplay: startIssuesToDisplay,\n autofocusRef: startAutofocusRef,\n handleFocus: handleStartFocus,\n } = useRegisterControl<TStart, HTMLInputElement>({\n controller: startController,\n issuesPanelLabel,\n ariaLabel: startInputProps?.[\"aria-label\"],\n issuesPanelLabelSuffix: issuesPanelStartLabelSuffix,\n preventAutoFocus,\n apiRef: startApiRef,\n });\n // Register the end control\n const {\n displayLoading: displayEndLoading,\n displayDisabled: displayEndDisabled,\n displayReadOnly: displayEndReadOnly,\n displayStatusToDisplay: endDisplayStatusToDisplay,\n issuesToDisplay: endIssuesToDisplay,\n autofocusRef: endAutofocusRef,\n handleFocus: handleEndFocus,\n } = useRegisterControl<TEnd, HTMLInputElement>({\n controller: endController,\n issuesPanelLabel,\n ariaLabel: endInputProps?.[\"aria-label\"],\n issuesPanelLabelSuffix: issuesPanelEndLabelSuffix,\n preventAutoFocus,\n apiRef: endApiRef,\n });\n\n const handleValueChange = useCallback(\n ({ formattedValue: newFormattedValue }: DateRangeValueRepresentations) => {\n setFormattedValue(newFormattedValue);\n if (newFormattedValue.start !== formattedValue.start) {\n startControllerInputProps.onChange(newFormattedValue.start);\n }\n if (newFormattedValue.end !== formattedValue.end) {\n endControllerInputProps.onChange(newFormattedValue.end);\n }\n },\n [\n endControllerInputProps,\n formattedValue.end,\n formattedValue.start,\n startControllerInputProps,\n ],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [startAbsolutePath.toString()]: startIssuesToDisplay,\n [endAbsolutePath.toString()]: endIssuesToDisplay,\n },\n issueMessages: {\n [startAbsolutePath.toString()]: startIssueMessages,\n [endAbsolutePath.toString()]: endIssueMessages,\n },\n displayIssues,\n issueMessagesProps,\n });\n\n return (\n <>\n <DateRangeInput\n value={formattedValue}\n locale={dateFnsLocale}\n shortFormat={shortFormat}\n fullFormat={fullFormat}\n required={\n required ??\n (startRestrictions.required === true ||\n endRestrictions.required === true)\n }\n minDate={minDate ?? minDateRestriction(startSchema)}\n maxDate={maxDate ?? maxDateRestriction(endSchema)}\n startLoading={displayStartLoading || startLoading}\n endLoading={displayEndLoading || endLoading}\n disabled={(displayStartDisabled && displayEndDisabled) || disabled}\n readOnly={\n (displayStartReadOnly && displayEndReadOnly) ||\n readOnly ||\n (startInputProps?.readOnly && endInputProps?.readOnly)\n }\n status={\n startDisplayStatusToDisplay === \"error\" ||\n endDisplayStatusToDisplay === \"error\"\n ? \"invalid\"\n : startDisplayStatusToDisplay === \"warning\" ||\n endDisplayStatusToDisplay === \"warning\"\n ? \"warned\"\n : undefined\n }\n onValueChange={combineEventHandlers(onValueChange, handleValueChange)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n combineEventHandlers(\n startControllerInputProps.onBlur,\n endControllerInputProps.onBlur,\n ),\n )}\n startInputProps={{\n name: startControllerInputProps.name,\n ...startInputProps,\n disabled: displayStartDisabled,\n readOnly: displayStartReadOnly || startInputProps?.readOnly,\n onFocus: combineEventHandlers(\n startInputProps?.onFocus,\n handleStartFocus,\n ),\n ref: useCombinedRef(\n startControllerInputProps?.ref,\n useCombinedRef(startAutofocusRef, startInputProps?.ref),\n ),\n }}\n endInputProps={{\n name: endControllerInputProps.name,\n ...endInputProps,\n disabled: displayEndDisabled,\n readOnly: displayEndReadOnly || endInputProps?.readOnly,\n onFocus: combineEventHandlers(endInputProps?.onFocus, handleEndFocus),\n ref: useCombinedRef(\n endControllerInputProps?.ref,\n useCombinedRef(endAutofocusRef, endInputProps?.ref),\n ),\n }}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n {...otherProps}\n ref={forwardedRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import { faDownload, faFileLines } from \"@fortawesome/free-solid-svg-icons\";\nimport type { File as KFormFile, Path } from \"@ostack.tech/kform\";\nimport {\n type FileInputController,\n type FileInputOptions,\n useFileInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n Alert,\n combineEventHandlers,\n ControlAddon,\n Dialog,\n DialogBody,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n Icon,\n IconButton,\n Input,\n Tooltip,\n useCombinedRef,\n usePrintClassNames,\n} from \"@ostack.tech/ui\";\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/**\n * File control's interaction with the selected file:\n *\n * - `view`: A button is added which opens a dialog to view and optionally\n * download the file. A fallback alert is displayed when the file cannot be\n * viewed.\n * - `download`: A button is added to download the file. Useful if you know that\n * the accepted file types aren't viewable in the browser.\n * - `none`: No interaction with the selected file is added.\n */\nexport type FileControlFileInteraction = \"view\" | \"download\" | \"none\";\n\n/** Properties of the file control component. */\nexport interface FileControlProps<T extends KFormFile | null = KFormFile | null>\n extends\n Omit<\n FileInputOptions<T, FileList, ComponentRef<typeof Input>>,\n \"enabled\" | \"formatFromFileList\" | \"parseToFileList\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Input>,\n // TODO: Support `multiple`\n | \"type\"\n | \"multiple\"\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"status\"\n | \"align\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n FileInputController<T, FileList, ComponentRef<typeof Input>> | undefined\n >;\n /**\n * Type of interaction with the selected file.\n *\n * @default view\n */\n fileInteraction?: FileControlFileInteraction;\n /** Label of the button used to open the file viewer. */\n viewFileButtonLabel?: ReactNode;\n /** Label of the button used to download the file. */\n downloadFileButtonLabel?: ReactNode;\n /** Text displayed when the file cannot be viewed. */\n fallbackText?: ReactNode;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** File control component supporting (possibly nullable) file schemas. */\nexport const FileControl = forwardRef(function FileControl<\n T extends KFormFile | null = KFormFile | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n fileInteraction = \"view\",\n viewFileButtonLabel,\n downloadFileButtonLabel,\n fallbackText,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n accept,\n loading,\n disabled,\n readOnly,\n showClearButton,\n endAdornment,\n onChange,\n onKeyDown,\n onFocus,\n onBlurToOutside,\n clearButtonProps,\n ...otherProps\n }: FileControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Input>>,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n viewFileButtonLabel ??= locale.FileControl.viewFileButtonLabel;\n downloadFileButtonLabel ??= locale.FileControl.downloadFileButtonLabel;\n fallbackText ??= locale.FileControl.fallbackText;\n const { printHidden } = usePrintClassNames();\n\n // Keep track of the latest file list to work around some browsers clearing\n // the input on \"cancel\"\n const latestFileList = useRef<FileList | null>(null);\n const [file, setFile] = useState<File | null>(null);\n const controller = useFileInput<T, FileList, ComponentRef<typeof Input>>(\n path,\n {\n enabled: !useFormIsLoading(),\n formManager,\n formatFromFileList: useCallback((fileList: FileList) => {\n setFile(fileList.length === 0 ? null : fileList[0]);\n latestFileList.current = fileList;\n return fileList;\n }, []),\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n },\n );\n const { useSchema, usePath, inputProps } = controller;\n const { nullable, restrictions } = useSchema().typeInfo;\n const absolutePath = usePath();\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLInputElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n // Prevent browsers from clearing the input on \"cancel\" by undoing clearings\n // that didn't originate from a click on the clear button or via\n // delete/backspace. This undoing is done by setting the input's `files` to\n // the latest seen file list.\n showClearButton ??= nullable ? \"auto\" : false;\n const isClearing = useRef(false);\n const handleClearButtonClick = useCallback(() => {\n isClearing.current = true;\n }, []);\n const handleChange = useCallback(\n (evt: ChangeEvent<HTMLInputElement>) => {\n if (evt.target.files!.length > 0 || isClearing.current) {\n isClearing.current = false;\n onChange?.(evt);\n inputProps.onChange(evt);\n } else {\n evt.target.files = latestFileList.current;\n }\n },\n [inputProps, onChange],\n );\n\n // Clear file when pressing 'Delete' or 'Backspace'\n const clearButtonRef = useRef<HTMLButtonElement | null>(null);\n const handleKeyDown = useCallback((evt: KeyboardEvent) => {\n if (evt.code === \"Delete\" || evt.code === \"Backspace\") {\n clearButtonRef.current?.click();\n }\n }, []);\n\n // File content as a data URL\n const dataURL = useMemo(\n () =>\n fileInteraction !== \"none\" && file ? URL.createObjectURL(file) : null,\n [file, fileInteraction],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedInputRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Input\n type=\"file\"\n name={inputProps.name}\n required={required ?? restrictions.required == true}\n accept={\n accept ??\n (Array.isArray(restrictions.acceptedFileTypes)\n ? restrictions.acceptedFileTypes.join()\n : undefined)\n }\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n showClearButton={showClearButton}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n onChange={handleChange}\n onKeyDown={combineEventHandlers(onKeyDown, handleKeyDown, {\n checkDefaultPrevented: true,\n })}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n clearButtonProps={{\n ...clearButtonProps,\n onClick: combineEventHandlers(\n clearButtonProps?.onClick,\n handleClearButtonClick,\n ),\n ref: useCombinedRef(clearButtonProps?.ref, clearButtonRef),\n }}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n\n {/* View file adornment */}\n {fileInteraction === \"view\" && file && (\n <Dialog>\n <Tooltip content={viewFileButtonLabel}>\n <DialogTrigger>\n <ControlAddon asChild>\n <button type=\"button\" className={printHidden}>\n <Icon fixedWidth icon={faFileLines} />\n </button>\n </ControlAddon>\n </DialogTrigger>\n </Tooltip>\n\n <DialogContent\n variant=\"subtle\"\n className={prefix(\"file-control__viewer-dialog\")}\n aria-describedby={undefined}\n >\n <DialogHeader>\n <DialogTitle\n className={prefix(\"file-control__viewer-dialog-title\")}\n >\n {file.name}\n </DialogTitle>\n\n {/* Download file */}\n <IconButton\n variant=\"ghost\"\n className={prefix(\"file-control__viewer-download\")}\n asChild\n icon={faDownload}\n label={downloadFileButtonLabel}\n >\n <a href={dataURL!} download={file.name} />\n </IconButton>\n </DialogHeader>\n\n <DialogBody\n className={prefix(\"file-control__viewer-dialog-body\")}\n >\n {/* File viewer */}\n <object\n className={prefix(\"file-control__viewer-object\")}\n type={file.type || undefined}\n data={dataURL!}\n aria-label={file.name}\n >\n <Alert\n className={prefix(\"file-control__viewer-fallback\")}\n severity=\"warning\"\n >\n {fallbackText}\n </Alert>\n </object>\n </DialogBody>\n </DialogContent>\n </Dialog>\n )}\n\n {/* File download adornment */}\n {fileInteraction === \"download\" && file && (\n <Tooltip content={downloadFileButtonLabel}>\n <ControlAddon asChild>\n <a\n className={printHidden}\n href={dataURL!}\n download={file.name}\n >\n <Icon icon={faDownload} />\n </a>\n </ControlAddon>\n </Tooltip>\n )}\n </>\n }\n {...otherProps}\n ref={combinedInputRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import {\n AbsolutePath,\n type DisplayStatus,\n type Path,\n type SealedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport {\n computed,\n useConstant,\n useLatestValues,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { useActivePathContext } from \"../../providers/ActivePathProvider\";\nimport { mostSpecificPath } from \"../../utils/mostSpecificPath.ts\";\nimport { useOnPathFocus } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport type { FormPageObject, FormPagesProps } from \"./FormPages.tsx\";\n\n/** Value of the form pages context. */\nexport type FormPagesContextValue = FormPagesStore;\n\n/** Resolved form page object. */\nexport interface ResolvedFormPageObject extends FormPageObject {\n path: AbsolutePath;\n}\n\n/** Form page state. */\nexport interface FormPageState {\n path: AbsolutePath;\n exists: boolean;\n deferredDisplayStatus: DisplayStatus | undefined;\n deferredIssuesToDisplay: SealedValidationIssue[];\n title?: ReactNode;\n documentTitle?: string | null;\n code?: ReactNode;\n}\n\n/** State of the form pages. */\nexport interface FormPagesState {\n pages: ResolvedFormPageObject[];\n activePage: AbsolutePath | null;\n activePageIndex: () => number;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new object\n // instances\n pageStates: [Record<string, FormPageState | null>];\n pageHeaderHeights: [Map<string, number>];\n navigationSelectHeight: number;\n actions: FormPagesActions;\n}\n\n/** Actions of the form pages. */\nexport interface FormPagesActions {\n getPageState: (path: AbsolutePath) => FormPageState | null;\n setPages: (pages: ResolvedFormPageObject[]) => void;\n setActivePage: (activePage: string | Path | null) => void;\n updateActivePage: (oldActivePageIndex: number) => void;\n registerPageState: (path: AbsolutePath, state: FormPageState) => void;\n setPageHeaderHeight: (path: AbsolutePath, height: number | null) => void;\n}\n\n/** Form pages store. */\nexport type FormPagesStore = ReturnType<typeof useCreateFormPagesContext>;\n\n/** Form pages context. */\nexport const FormPagesContext = createContext<FormPagesContextValue | null>(\n null,\n);\n\n/** Options used to create the form pages context. */\nexport interface UseCreateFormPagesContextOptions extends Pick<\n FormPagesProps,\n \"defaultActivePage\" | \"activePage\" | \"onActivePageChange\"\n> {\n basePath: AbsolutePath;\n resolvedPages: ResolvedFormPageObject[];\n}\n\n/** Hook used to create the form pages context. */\nexport function useCreateFormPagesContext({\n basePath,\n resolvedPages,\n defaultActivePage,\n activePage,\n onActivePageChange,\n}: UseCreateFormPagesContextOptions) {\n const setLatestInteraction = useSetLatestInteraction();\n const { activePath, onActivePathChange } = useActivePathContext();\n activePage ??= activePath;\n const latest = useLatestValues({\n printing: usePrinting(),\n onActivePathChange,\n onActivePageChange,\n });\n\n const store = useConstant(() =>\n createStore<FormPagesState>()(\n subscribeWithSelector((set, get) => ({\n pages: resolvedPages,\n activePage:\n activePage === undefined\n ? defaultActivePage == null\n ? null\n : basePath.resolve(defaultActivePage)\n : activePage === null\n ? null\n : basePath.resolve(activePage),\n activePageIndex: computed(\n () => [get().pages, get().activePage],\n (pages, activePage) =>\n activePage === null\n ? -1\n : pages.findIndex((page) => page.path.equals(activePage)),\n ),\n pageStates: [{}],\n pageHeaderHeights: [new Map()],\n navigationSelectHeight: 0,\n actions: {\n getPageState: (path) => get().pageStates[0][path.toString()] ?? null,\n setPages: (pages) => {\n const oldActivePageIndex = get().activePageIndex();\n const newPageStates: Record<string, FormPageState | null> = {};\n for (const page of pages) {\n newPageStates[page.path.toString()] = get().actions.getPageState(\n page.path,\n );\n }\n set({ pages, pageStates: [newPageStates] });\n get().actions.updateActivePage(oldActivePageIndex);\n },\n setActivePage: (path: string | Path | null) => {\n if (latest.printing) {\n return;\n }\n\n const newActivePage =\n path === null || path instanceof AbsolutePath\n ? path\n : new AbsolutePath(path);\n const oldActivePage = get().activePage;\n if (!oldActivePage?.equals(newActivePage)) {\n startTransition(() => {\n set({ activePage: newActivePage });\n if (newActivePage != null) {\n setLatestInteraction(newActivePage);\n }\n latest.onActivePathChange(newActivePage);\n latest.onActivePageChange?.(newActivePage);\n });\n }\n },\n updateActivePage: (oldActivePageIndex: number) => {\n if (\n latest.printing ||\n (get().activePage !== null &&\n get().pages.some((page) => page.path.equals(get().activePage)))\n ) {\n return;\n }\n\n get().actions.setActivePage(\n get().pages[\n Math.max(\n 0,\n Math.min(oldActivePageIndex, get().pages.length - 1),\n )\n ]?.path ?? null,\n );\n },\n registerPageState: (path, state) => {\n const oldActivePageIndex = get().activePageIndex();\n const pageStates = get().pageStates[0];\n pageStates[path.toString()] = state;\n set({ pageStates: [pageStates] });\n get().actions.updateActivePage(oldActivePageIndex);\n },\n setPageHeaderHeight: (path, height) => {\n if (latest.printing) {\n return;\n }\n\n const {\n pageHeaderHeights: [pageHeaderHeights],\n } = get();\n if (height != null) {\n pageHeaderHeights.set(path.toString(), height);\n } else {\n pageHeaderHeights.delete(path.toString());\n }\n set({ pageHeaderHeights: [pageHeaderHeights] });\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.getState().actions.setPages(resolvedPages);\n if (activePage !== undefined) {\n const { pages, activePage: oldActivePage } = store.getState();\n store.getState().actions.setActivePage(\n mostSpecificPath(\n activePage === null ? null : basePath.resolve(activePage),\n pages.map((page) => page.path),\n oldActivePage,\n ) ?? null,\n );\n }\n }, [resolvedPages, activePage, basePath, store]);\n\n // Set (possibly new) active page when focused path changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const { pages, activePage, actions } = store.getState();\n actions.setActivePage(\n mostSpecificPath(\n focusedPath,\n pages.map((page) => page.path),\n activePage,\n ) ?? null,\n );\n },\n [store],\n ),\n );\n\n return store;\n}\n\nexport function useFormPagesContext(): FormPagesContextValue {\n const formPagesContext = useContext(FormPagesContext);\n if (!formPagesContext) {\n throw new Error(\"Form pages context not in scope.\");\n }\n return formPagesContext;\n}\n\nexport function useFormPageState<T>(\n path: AbsolutePath,\n selector: (state: FormPageState | null) => T,\n): T {\n return useStore(useFormPagesContext(), (state) =>\n selector(state.actions.getPageState(path)),\n );\n}\n","import { faCircleQuestion } from \"@fortawesome/free-solid-svg-icons\";\nimport { useCurrentPath } from \"@ostack.tech/kform-react\";\nimport {\n boolDataAttr,\n controlStatusToAccent,\n cx,\n IconButton,\n Popover,\n PopoverContent,\n PopoverTrigger,\n Stack,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\nimport { useShallow } from \"zustand/react/shallow\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useIssuesDisplayMode } from \"../FormApp\";\nimport { IssueMessages } from \"../IssueMessages\";\nimport { IssuesPopover } from \"../IssuesPopover\";\nimport type { FormPageProps } from \"./FormPage.tsx\";\nimport { useFormPageState } from \"./FormPagesContext.ts\";\n\n/** Properties of the form page header. */\nexport interface FormPageHeaderProps\n extends\n ComponentPropsWithoutRef<\"div\">,\n Pick<\n FormPageProps,\n | \"helperText\"\n | \"helperButtonLabel\"\n | \"ownIssueMessages\"\n | \"codeProps\"\n | \"titleProps\"\n | \"headerPopoverContainerProps\"\n | \"issuesPopoverProps\"\n | \"issueMessagesProps\"\n | \"helperButtonProps\"\n | \"helperPopoverProps\"\n | \"helperPopoverContentProps\"\n > {}\n\n/** Form page header. */\nexport const FormPageHeader = forwardRef<\n ComponentRef<\"div\">,\n FormPageHeaderProps\n>(function FormPageHeader(\n {\n helperText,\n helperButtonLabel,\n ownIssueMessages,\n codeProps,\n titleProps,\n headerPopoverContainerProps,\n issuesPopoverProps,\n issueMessagesProps,\n helperButtonProps,\n helperPopoverProps,\n helperPopoverContentProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const printing = usePrinting();\n const currentPath = useCurrentPath();\n const issuesDisplayMode = useIssuesDisplayMode();\n\n const deferredIssuesToDisplay =\n useFormPageState(\n currentPath,\n useShallow(\n (state) =>\n (!printing &&\n issuesDisplayMode === \"inline\" &&\n state?.deferredIssuesToDisplay) ||\n [],\n ),\n ) ?? [];\n const deferredDisplayStatus = useFormPageState(currentPath, (state) =>\n printing ? undefined : state?.deferredDisplayStatus,\n );\n const code = useFormPageState(currentPath, (state) => state?.code);\n const title = useFormPageState(currentPath, (state) => state?.title);\n\n return (\n <div\n className={cx(prefix(\"form-pages__page-header\"), className)}\n {...otherProps}\n data-has-popovers={boolDataAttr(\n helperText != null || deferredIssuesToDisplay.length > 0,\n )}\n ref={forwardedRef}\n >\n {/* Form page code */}\n <div\n {...codeProps}\n className={cx(prefix(\"form-pages__page-code\"), codeProps?.className)}\n data-status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-accent={controlStatusToAccent(\n displayStatusToControlStatus(deferredDisplayStatus),\n )}\n >\n {code}\n </div>\n\n {/* Form page title */}\n <h2\n {...titleProps}\n className={cx(prefix(\"form-pages__page-title\"), titleProps?.className)}\n >\n {title}\n </h2>\n\n {/* Form page issues */}\n {!printing && (\n <Stack\n direction=\"row\"\n gap={0}\n {...headerPopoverContainerProps}\n className={cx(\n prefix(\"form-pages__page-header-popovers\"),\n headerPopoverContainerProps?.className,\n )}\n >\n {issuesDisplayMode === \"inline\" && (\n <IssuesPopover\n side=\"bottom\"\n {...issuesPopoverProps}\n iconButtonProps={{\n className: cx(\n prefix(\"form-pages__page-issues-popover-button\"),\n issuesPopoverProps?.iconButtonProps?.className,\n ),\n ...issuesPopoverProps?.iconButtonProps,\n }}\n >\n <IssueMessages\n issues={deferredIssuesToDisplay}\n messages={ownIssueMessages}\n {...issueMessagesProps}\n />\n </IssuesPopover>\n )}\n\n {/* Form page helper text */}\n {helperText && (\n <Popover modal={false} {...helperPopoverProps}>\n <PopoverTrigger>\n <IconButton\n circle\n color=\"primary\"\n variant=\"ghost\"\n icon={faCircleQuestion}\n label={helperButtonLabel ?? \"\"}\n {...helperButtonProps}\n tooltipProps={{\n side: \"bottom\",\n ...helperButtonProps?.tooltipProps,\n }}\n className={cx(\n prefix(\"form-pages__page-helper-button\"),\n helperButtonProps?.className,\n )}\n />\n </PopoverTrigger>\n\n <PopoverContent\n {...helperPopoverContentProps}\n className={cx(\n prefix(\"form-pages__page-helper-popover\"),\n helperPopoverContentProps?.className,\n )}\n >\n {helperText}\n </PopoverContent>\n </Popover>\n )}\n </Stack>\n )}\n </div>\n );\n});\n","import { CurrentPath, useResolvedPath } from \"@ostack.tech/kform-react\";\nimport {\n Container,\n cx,\n DocumentTitle,\n ErrorBoundary,\n type IconButton,\n type Popover,\n type PopoverContent,\n Spinner,\n type Stack,\n useCombinedRef,\n useMeasure,\n usePrinting,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n Suspense,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport {\n FormAppIssueMessages,\n FormAppStatus,\n useFormAppElement,\n} from \"../FormApp\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\nimport type { IssuesPopover } from \"../IssuesPopover\";\nimport { FormPageHeader } from \"./FormPageHeader.tsx\";\nimport type { FormPageObject } from \"./FormPages.tsx\";\nimport { useFormPagesContext, useFormPageState } from \"./FormPagesContext.ts\";\n\n/** Properties of the form page component. */\nexport interface FormPageProps\n extends\n FormPageObject,\n Omit<ComponentPropsWithoutRef<\"div\">, \"title\" | \"children\"> {\n /** Sets the form page as disabled. */\n disabled?: boolean;\n /** Sets the form page as read-only. */\n readOnly?: boolean;\n /** Form page helper text, displayed as a popover triggered by an icon button. */\n helperText?: ReactNode;\n /**\n * Mapping of issue messages from the path of the field with issues to the\n * issue messages of said field (which are themselves grouped by their code).\n *\n * Provided paths are relative to the form page's path and may contain\n * wildcards, which will have a lower priority when matched against.\n *\n * These messages are used by the `IssueMessages` component.\n *\n * **Note:** Changes to `issueMessages` are handled correctly, but are not\n * efficient. Please make sure that the identity of the provided value doesn't\n * change at every render.\n *\n * Example value:\n *\n * ```tsx\n * {\n * \"**\": {\n * \"valueMissing\": \"Field is required.\"\n * },\n * \"field\": {\n * \"valueMissing\": \"My field cannot be left empty!\",\n * \"someOtherError\": \"Text of the other error.\"\n * }\n * }\n * ```\n */\n issueMessages?: Record<string, IssueMessagesByCode>;\n /**\n * Issue messages of the form page itself.\n *\n * These messages can also be provided via the `issueMessages` property using\n * a path of \"`.`\".\n */\n ownIssueMessages?: IssueMessagesByCode;\n /** Properties to pass to the header element. */\n headerProps?: ComponentPropsWithRef<\"div\">;\n /** Label of the helper button announced to assistive technologies. */\n helperButtonLabel?: string;\n /** Properties to pass to the code element. */\n codeProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the title element. */\n titleProps?: ComponentPropsWithRef<\"h2\">;\n /**\n * Properties to pass to the element containing the popover components in the\n * header.\n */\n headerPopoverContainerProps?: ComponentPropsWithRef<typeof Stack>;\n /** Properties to pass to the form page's issues popover component. */\n issuesPopoverProps?: ComponentPropsWithRef<typeof IssuesPopover>;\n /** Properties to pass to the form page's issue messages component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"messages\"\n >;\n /** Properties to pass to the content element. */\n contentProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the container component. */\n containerProps?: ComponentPropsWithRef<typeof Container>;\n /** Properties to pass to the `ErrorBoundary` component. */\n errorBoundaryProps?: ComponentPropsWithRef<typeof ErrorBoundary>;\n /** Properties to pass to the helper button component. */\n helperButtonProps?: Omit<ComponentPropsWithRef<typeof IconButton>, \"icon\">;\n /** Properties to pass to the helper popover component. */\n helperPopoverProps?: ComponentPropsWithRef<typeof Popover>;\n /** Properties to pass to the helper popover content component. */\n helperPopoverContentProps?: ComponentPropsWithRef<typeof PopoverContent>;\n children?: ReactNode;\n}\n\n/** Form page component. */\nexport const FormPage = forwardRef<ComponentRef<\"div\">, FormPageProps>(\n function FormPage(\n {\n path,\n // `FormPageObject` props\n title: _title,\n documentTitle: _documentTitle,\n code: _code,\n issuesPanelLabel: _issuesPanelLabel,\n disabled = false,\n readOnly = false,\n className,\n helperText,\n helperButtonLabel,\n issueMessages,\n ownIssueMessages,\n headerProps,\n codeProps,\n titleProps,\n headerPopoverContainerProps,\n issuesPopoverProps,\n issueMessagesProps,\n contentProps,\n containerProps,\n errorBoundaryProps,\n helperButtonProps,\n helperPopoverProps,\n helperPopoverContentProps,\n children,\n ...otherProps\n },\n forwardedRef,\n ) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n helperButtonLabel ??= locale.FormPage.helperButtonLabel;\n const printing = usePrinting();\n\n const store = useFormPagesContext();\n const pagePath = useResolvedPath(path);\n\n const activePage = useStore(store, (state) => state.activePage);\n const shouldDisplay = useFormPageState(pagePath, (state) =>\n state?.path.equals(activePage),\n );\n const documentTitle = useFormPageState(pagePath, (state) =>\n state === null ? null : state.documentTitle,\n );\n\n if (documentTitle === undefined) {\n warnOnce(\n `FormPage: At '${pagePath.toString()}': \\`documentTitle\\` ` +\n \"should be set manually since the form page's `title` is not a string.\",\n );\n }\n\n // Keep track of the page header's height\n const [headerEl, setHeaderEl] = useState<HTMLDivElement | null>(null);\n useMeasure(\n headerEl,\n useCallback(\n (measurement) => {\n store\n .getState()\n .actions.setPageHeaderHeight(pagePath, measurement?.height ?? null);\n },\n [pagePath, store],\n ),\n );\n\n // Scroll to the top of the form app whenever we first change into a page\n const formAppEl = useFormAppElement();\n const isFirstDisplay = useRef(true);\n useEffect(() => {\n if (shouldDisplay && !printing && isFirstDisplay.current) {\n formAppEl.scrollIntoView(true);\n isFirstDisplay.current = false;\n return () => {\n isFirstDisplay.current = true;\n };\n }\n }, [formAppEl, printing, shouldDisplay]);\n\n const combinedHeaderRef = useCombinedRef(setHeaderEl, headerProps?.ref);\n return shouldDisplay || printing ? (\n <CurrentPath path={pagePath}>\n <DocumentTitle\n title={printing ? undefined : (documentTitle ?? undefined)}\n >\n <div\n className={cx(prefix(\"form-pages__page\"), className)}\n {...otherProps}\n ref={forwardedRef}\n >\n <FormAppStatus disabled={disabled} readOnly={readOnly}>\n <FormAppIssueMessages issueMessages={issueMessages}>\n <FormPageHeader\n helperText={helperText}\n helperButtonLabel={helperButtonLabel}\n ownIssueMessages={ownIssueMessages}\n codeProps={codeProps}\n titleProps={titleProps}\n headerPopoverContainerProps={headerPopoverContainerProps}\n issuesPopoverProps={issuesPopoverProps}\n issueMessagesProps={issueMessagesProps}\n helperButtonProps={helperButtonProps}\n helperPopoverProps={helperPopoverProps}\n helperPopoverContentProps={helperPopoverContentProps}\n {...headerProps}\n ref={combinedHeaderRef}\n />\n\n <div\n {...contentProps}\n className={cx(\n prefix(\"form-pages__page-content\"),\n contentProps?.className,\n )}\n >\n <Container fluid=\"md\" gutter={0} {...containerProps}>\n <ErrorBoundary {...errorBoundaryProps}>\n <Suspense\n fallback={<Spinner size=\"xl\" color=\"primary\" />}\n >\n {children}\n </Suspense>\n </ErrorBoundary>\n </Container>\n </div>\n </FormAppIssueMessages>\n </FormAppStatus>\n </div>\n </DocumentTitle>\n </CurrentPath>\n ) : null;\n },\n);\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { CurrentPath, useController } from \"@ostack.tech/kform-react\";\nimport { usePrinting, useStartPrintingTask } from \"@ostack.tech/ui\";\nimport { useDeferredValue, useEffect } from \"react\";\nimport { shallow } from \"zustand/shallow\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedFormPageObject,\n useFormPagesContext,\n} from \"./FormPagesContext.ts\";\n\n/** Properties of the `FormPageRegistrar` component. */\nexport interface FormPageRegistrarProps extends ResolvedFormPageObject {}\n\n/** Component used to register a form page. */\nexport function FormPageRegistrar({\n path,\n title,\n documentTitle,\n code,\n issuesPanelLabel,\n}: FormPageRegistrarProps) {\n const store = useFormPagesContext();\n\n const printing = usePrinting();\n const finishPrintingTask = useStartPrintingTask();\n const controller = useController(\n path.append(AbsolutePathFragment.RecursiveWildcard),\n { enabled: !useFormIsLoading(), onInitialized: finishPrintingTask },\n );\n const absolutePath = controller.usePath();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n const value = controller.useValue();\n const deferredValue = useDeferredValue(value);\n const relevantValue = printing ? value : deferredValue;\n const deferredIssuesToDisplay = useDeferredValue(\n controller.useState((state) => (state.touched ? state.issues : []), {\n equalityFn: shallow,\n }),\n );\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n const actualTitle =\n typeof title === \"function\"\n ? relevantValue === undefined\n ? null\n : title(relevantValue)\n : title;\n const actualDocumentTitle =\n typeof documentTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : documentTitle(relevantValue)\n : documentTitle === undefined\n ? actualTitle === null || typeof actualTitle === \"string\"\n ? actualTitle\n : undefined\n : documentTitle;\n\n useEffect(() => {\n const { registerPageState } = store.getState().actions;\n registerPageState(absolutePath, {\n exists,\n path: absolutePath,\n deferredIssuesToDisplay,\n deferredDisplayStatus,\n title: actualTitle,\n documentTitle: actualDocumentTitle,\n code,\n });\n }, [\n absolutePath,\n actualDocumentTitle,\n actualTitle,\n code,\n deferredDisplayStatus,\n deferredIssuesToDisplay,\n exists,\n store,\n title,\n ]);\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>\n {typeof issuesPanelLabel === \"function\"\n ? deferredValue === undefined\n ? null\n : issuesPanelLabel(deferredValue)\n : issuesPanelLabel || actualTitle}\n </CurrentPath>,\n );\n\n return null;\n}\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n Path,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n useFormManager,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport {\n cx,\n useCombinedRef,\n useCssVars,\n useMediaBreakpointUp,\n} from \"@ostack.tech/ui\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormPage, type FormPageProps } from \"./FormPage.tsx\";\nimport { FormPageRegistrar } from \"./FormPageRegistrar.tsx\";\nimport {\n FormPagesContext,\n useCreateFormPagesContext,\n} from \"./FormPagesContext.ts\";\n\n/** Properties of the form page component. */\nexport interface FormPagesProps extends ComponentPropsWithoutRef<\"div\"> {\n /** Base path for all declared form pages. */\n path?: string | Path;\n /**\n * List of all form pages. When not provided, the list of pages is obtained\n * from the direct children `FormPage` components.\n */\n pages?: FormPageObject[];\n /** Default active form page. */\n defaultActivePage?: string | Path;\n /** Controlled active form page. */\n activePage?: string | Path;\n /**\n * Function called whenever the active form page changes.\n *\n * @param activePagePath Path of the new active form page.\n */\n onActivePageChange?: (activePagePath: AbsolutePath | null) => void;\n children?: ReactNode;\n}\n\n/** Object representation of a form page. */\nexport interface FormPageObject<T = any> {\n /** Form page path. */\n path?: string | Path;\n /** Form page's title */\n title?: ReactNode | ((value: T) => ReactNode);\n /**\n * Title of the form page as a string to display in the document's title.\n *\n * Defaults to `title` when it is a string. A warning is printed if `title` is\n * not a string and `documentTitle` is not provided.\n */\n documentTitle?: string | null | ((value: T) => string | null);\n /** Form page's code. */\n code?: ReactNode;\n /** Form page's label in the issues panel. The `title` is used by default. */\n issuesPanelLabel?: ReactNode | ((value: T) => ReactNode);\n}\n\n/** Root component used to render form pages. */\nexport const FormPages = forwardRef<ComponentRef<\"div\">, FormPagesProps>(\n function FormPages(\n {\n path,\n pages,\n defaultActivePage,\n activePage,\n onActivePageChange,\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n ) {\n const prefix = usePrefix();\n const { cssVarName } = useCssVars({ prefix });\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n\n pages ??= Children.toArray(children)\n .filter(\n (child): child is ReactElement<FormPageProps, typeof FormPage> =>\n isValidElement(child) && child.type === FormPage,\n )\n .map((child) => ({\n path: child.props.path,\n title: child.props.title,\n documentTitle: child.props.documentTitle,\n code: child.props.code,\n issuesPanelLabel: child.props.issuesPanelLabel,\n }));\n\n // Provided pages but with absolute paths\n const resolvedPages = useMemo(\n () =>\n pages.map((page) => ({\n ...page,\n path: absolutePath.resolve(page.path ?? Path.CURRENT),\n })),\n [absolutePath, pages],\n );\n\n // Refuse non-existent paths\n if (!formManager.isValidPath(absolutePath)) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form pages base path must only contain ids.\");\n }\n // Validate form page paths\n for (const page of resolvedPages) {\n // Refuse non-existent paths\n if (!formManager.isValidPath(page.path)) {\n throw new Error(`Invalid path: '${page.path.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n page.path.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form page path must only contain ids.\");\n }\n }\n\n const store = useCreateFormPagesContext({\n basePath: absolutePath,\n resolvedPages,\n defaultActivePage,\n activePage,\n onActivePageChange,\n });\n\n const formPagesRef = useRef<HTMLDivElement | null>(null);\n\n // Active page header height\n useEffect(\n () =>\n store.subscribe(\n ({ activePage, pageHeaderHeights: [pageHeaderHeights] }) =>\n (activePage && pageHeaderHeights.get(activePage.toString())) ?? 0,\n (height) =>\n formPagesRef.current?.style.setProperty(\n cssVarName(\"form-pages-page-header-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, prefix, store],\n );\n\n // Navigation select height\n useEffect(\n () =>\n store.subscribe(\n (state) => state.navigationSelectHeight,\n (height) =>\n formPagesRef.current?.style.setProperty(\n cssVarName(\"form-pages-navigation-select-height\"),\n `${height}px`,\n ),\n { fireImmediately: true },\n ),\n [cssVarName, prefix, store],\n );\n\n const combinedFormPagesRef = useCombinedRef(formPagesRef, forwardedRef);\n return (\n <CurrentPath path={absolutePath}>\n <FormPagesContext.Provider value={store}>\n {resolvedPages.map((page) => (\n <FormPageRegistrar key={page.path.toString()} {...page} />\n ))}\n\n <div\n className={cx(prefix(\"form-pages\"), className)}\n data-navigation-mode={isLargeScreen ? \"sidebar\" : \"select\"}\n {...otherProps}\n ref={combinedFormPagesRef}\n >\n {children}\n </div>\n </FormPagesContext.Provider>\n </CurrentPath>\n );\n },\n);\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport { controlStatusToAccent, Option } from \"@ostack.tech/ui\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useFormPageState } from \"./FormPagesContext.ts\";\n\ninterface FormPagesSelectOptionProps {\n path: AbsolutePath;\n}\n\nexport function FormPagesSelectOption({ path }: FormPagesSelectOptionProps) {\n const prefix = usePrefix();\n const disabled = useFormPageState(path, (state) => !state?.exists);\n const deferredDisplayStatus = useFormPageState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const code = useFormPageState(path, (state) => state?.code);\n const title = useFormPageState(path, (state) => state?.title);\n const controlStatus = displayStatusToControlStatus(deferredDisplayStatus);\n const accent = controlStatusToAccent(controlStatus, \"primary\");\n\n return (\n <CurrentPath path={path}>\n <Option\n value={path.toString()}\n keywords={[\n ...(typeof code === \"string\" ? [code] : []),\n ...(typeof title === \"string\" ? [title] : []),\n ]}\n className={prefix(\"form-pages__select-option\")}\n color={accent}\n disabled={disabled}\n iconProps={{\n className: prefix(\"form-pages__select-option-indicator\"),\n }}\n >\n <span\n className={prefix(\"form-pages__select-option-code\")}\n data-status={controlStatus}\n data-accent={accent}\n >\n {code}\n </span>\n {title}\n </Option>\n </CurrentPath>\n );\n}\n","import { AbsolutePath } from \"@ostack.tech/kform\";\nimport { cx, Select, useCombinedRef, useMeasure } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormPagesContext } from \"./FormPagesContext.ts\";\nimport { FormPagesSelectOption } from \"./FormPagesSelectOption.tsx\";\n\n/** Properties of the form pages select component. */\nexport interface FormPagesSelectProps extends Omit<\n ComponentPropsWithoutRef<typeof Select>,\n \"multiple\" | \"defaultValue\" | \"value\" | \"onValueChange\" | \"showClearButton\"\n> {}\n\n/** Select component allowing the navigation between form pages. */\nexport const FormPagesSelect = forwardRef<\n ComponentRef<typeof Select>,\n FormPagesSelectProps\n>(function FormPagesSelect(\n {\n rootProps,\n containerProps,\n valueProps,\n arrowProps,\n popoverProps,\n commandMenuProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const store = useFormPagesContext();\n const activePage = useStore(store, (state) => state.activePage);\n\n // Keep track of the select root's height\n const [selectRootEl, setSelectRootEl] = useState<HTMLDivElement | null>(null);\n useMeasure(\n selectRootEl,\n useCallback(\n (measurement) => {\n store.setState({ navigationSelectHeight: measurement?.height ?? 0 });\n },\n [store],\n ),\n );\n\n const handleValueChange = useCallback(\n (value: string) =>\n value && store.getState().actions.setActivePage(new AbsolutePath(value)),\n [store],\n );\n\n const pages = useStore(store, (state) => state.pages);\n return (\n <Select\n className={cx(prefix(\"form-pages__select\"), className)}\n value={activePage?.toString() ?? \"\"}\n onValueChange={handleValueChange}\n showClearButton={false}\n rootProps={{\n ...rootProps,\n ref: useCombinedRef(\n setSelectRootEl as (el: HTMLDivElement) => void,\n rootProps?.ref,\n ),\n }}\n containerProps={{\n ...containerProps,\n className: cx(\n prefix(\"form-pages__select-container\"),\n containerProps?.className,\n ),\n }}\n valueProps={{\n ...valueProps,\n className: cx(\n prefix(\"form-pages__select-value\"),\n valueProps?.className,\n ),\n }}\n arrowProps={{\n ...arrowProps,\n className: cx(\n prefix(\"form-pages__select-arrow\"),\n arrowProps?.className,\n ),\n }}\n popoverProps={{\n ...popoverProps,\n className: cx(\n prefix(\"form-pages__select-popover\"),\n popoverProps?.className,\n ),\n }}\n commandMenuProps={{ variant: \"subtle\", ...commandMenuProps }}\n {...otherProps}\n ref={forwardedRef}\n >\n {pages.map((page) => (\n <FormPagesSelectOption key={page.path.toString()} path={page.path} />\n ))}\n </Select>\n );\n});\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport {\n boolDataAttr,\n controlStatusToAccent,\n MenuListItem,\n} from \"@ostack.tech/ui\";\nimport { useCallback, useRef } from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { visiblyFocus } from \"../../utils/useControlAutofocus.ts\";\nimport { useIssuesDisplayMode, useOnPathFocus } from \"../FormApp\";\nimport { useResetFocus } from \"../FormApp/FormAppContext.ts\";\nimport { useFormPagesContext, useFormPageState } from \"./FormPagesContext.ts\";\n\ninterface FormPageSidebarItemProps {\n path: AbsolutePath;\n}\n\nexport function FormPageSidebarItem({ path }: FormPageSidebarItemProps) {\n const prefix = usePrefix();\n const store = useFormPagesContext();\n const activePage = useStore(store, (state) => state.activePage);\n\n const handleClick = () => store.getState().actions.setActivePage(path);\n\n const disabled = useFormPageState(path, (state) => !state?.exists);\n const deferredDisplayStatus = useFormPageState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const code = useFormPageState(path, (state) => state?.code);\n const title = useFormPageState(path, (state) => state?.title);\n\n const issuesDisplayMode = useIssuesDisplayMode();\n const itemActionRef = useRef<HTMLButtonElement | null>(null);\n const resetFocus = useResetFocus();\n useOnPathFocus(\n useCallback(\n (focusedPath: AbsolutePath) => {\n if (itemActionRef.current && path.equals(focusedPath)) {\n // In inline mode the issues popover should get focused instead\n if (issuesDisplayMode === \"panel\") {\n visiblyFocus(itemActionRef.current);\n }\n // Let the form page be opened before resetting focus\n setTimeout(() => resetFocus());\n }\n },\n [issuesDisplayMode, path, resetFocus],\n ),\n );\n\n const isSelected = activePage?.equals(path);\n return (\n <MenuListItem\n className={prefix(\"form-pages__sidebar-item\")}\n selected={isSelected}\n disabled={disabled}\n onSelect={handleClick}\n color=\"primary\"\n contentProps={{ className: prefix(\"form-pages__sidebar-item-content\") }}\n actionProps={{ ref: itemActionRef }}\n >\n <CurrentPath path={path}>\n <span\n className={prefix(\"form-pages__sidebar-item-code\")}\n data-selected={boolDataAttr(isSelected)}\n data-status={displayStatusToControlStatus(deferredDisplayStatus)}\n data-accent={controlStatusToAccent(\n displayStatusToControlStatus(deferredDisplayStatus),\n )}\n >\n {code}\n </span>\n {title}\n </CurrentPath>\n </MenuListItem>\n );\n}\n","import { AbsolutePathFragment } from \"@ostack.tech/kform\";\nimport { useFormContext } from \"@ostack.tech/kform-react\";\nimport { cx, MenuList, useCombinedRef, useMeasure } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useSetLeftSidebarWidth } from \"../FormApp\";\nimport { useFormPagesContext } from \"./FormPagesContext.ts\";\nimport { FormPageSidebarItem } from \"./FormPageSidebarItem.tsx\";\n\n/** Properties of the form pages sidebar component. */\nexport interface FormPagesSidebarProps extends ComponentPropsWithoutRef<\"aside\"> {}\n\n/** Sidebar component allowing the navigation between form pages. */\nexport const FormPagesSidebar = forwardRef<\n ComponentRef<\"aside\">,\n FormPagesSidebarProps\n>(function FormPagesSidebar({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n const store = useFormPagesContext();\n const { currentPath } = useFormContext();\n const activePage = useStore(store, (state) => state.activePage);\n const setLeftSidebarWidth = useSetLeftSidebarWidth();\n\n // Inform form app of \"active\" form pages navigation components (affect the\n // positioning of the issues panel when the sidebar is visible)\n const [sidebarEl, setSidebarEl] = useState<HTMLElement | null>(null);\n useMeasure(\n sidebarEl,\n useCallback(\n (measurement) => {\n if (\n activePage &&\n currentPath\n .append(AbsolutePathFragment.RecursiveWildcard)\n .contains(activePage)\n ) {\n setLeftSidebarWidth(measurement?.width);\n }\n },\n [activePage, currentPath, setLeftSidebarWidth],\n ),\n );\n\n const pages = useStore(store, (state) => state.pages);\n const combinedSidebarRef = useCombinedRef(setSidebarEl, forwardedRef);\n return (\n <aside\n className={cx(prefix(\"form-pages__sidebar\"), className)}\n {...otherProps}\n ref={combinedSidebarRef}\n >\n <MenuList>\n {pages.map((page) => (\n <FormPageSidebarItem key={page.path.toString()} path={page.path} />\n ))}\n </MenuList>\n </aside>\n );\n});\n","import { cx, useMediaBreakpointUp, usePrintClassNames } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormPagesSelect } from \"./FormPagesSelect.tsx\";\nimport { FormPagesSidebar } from \"./FormPagesSidebar.tsx\";\n\n/** Properties of the form pages navigation component. */\nexport interface FormPagesNavigationProps extends ComponentPropsWithoutRef<\"nav\"> {\n /** Properties to pass to the sidebar component. */\n sidebarProps?: ComponentPropsWithRef<typeof FormPagesSidebar>;\n /** Properties to pass to the select component. */\n selectProps?: ComponentPropsWithRef<typeof FormPagesSelect>;\n}\n\n/** Component allowing the navigation between form pages. */\nexport const FormPagesNavigation = forwardRef<\n ComponentRef<\"nav\">,\n FormPagesNavigationProps\n>(function FormPagesNavigation(\n {\n sidebarProps,\n selectProps,\n className,\n \"aria-label\": ariaLabel,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n ariaLabel ??= locale.FormPagesNavigation[\"aria-label\"];\n const { printHidden } = usePrintClassNames();\n const isLargeScreen = useMediaBreakpointUp(\"sm\");\n\n return (\n <nav\n className={cx(prefix(\"form-pages__navigation\"), printHidden, className)}\n data-navigation-mode={isLargeScreen ? \"sidebar\" : \"select\"}\n aria-label={ariaLabel}\n {...otherProps}\n ref={forwardedRef}\n >\n {isLargeScreen ? (\n <FormPagesSidebar {...sidebarProps} />\n ) : (\n <FormPagesSelect {...selectProps} />\n )}\n </nav>\n );\n});\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n type DisplayStatus,\n type FormManager,\n} from \"@ostack.tech/kform\";\nimport { useConstant, useLatestValues, usePrinting } from \"@ostack.tech/ui\";\nimport {\n createContext,\n type ReactNode,\n startTransition,\n useCallback,\n useContext,\n useEffect,\n} from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { useActivePathContext } from \"../../providers/ActivePathProvider\";\nimport { mostSpecificPath } from \"../../utils/mostSpecificPath.ts\";\nimport { useFocus, useOnPathFocus } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport type { FormStepObject, FormStepperProps } from \"./FormStepper.tsx\";\n\n/** Value of the form stepper context. */\nexport type FormStepperContextValue = FormStepperStore;\n\n/** Resolved form step object. */\nexport interface ResolvedFormStepObject extends FormStepObject {\n path: AbsolutePath;\n index: number;\n}\n\n/** Form step state. */\nexport interface FormStepState {\n path: AbsolutePath;\n index: number;\n exists: boolean;\n deferredDisplayStatus: DisplayStatus | undefined;\n title?: ReactNode;\n documentTitle?: string | null;\n}\n\n/** State of the form stepper. */\nexport interface FormStepperState {\n steps: ResolvedFormStepObject[];\n activeStep: ResolvedFormStepObject | null;\n // State below is wrapped in an array in order to trigger state updates by\n // simply changing the identity of the wrapper without creating new map\n // instances\n stepStates: [Record<string, FormStepState | null>];\n actions: FormStepperActions;\n}\n\n/** Actions of the form stepper. */\nexport interface FormStepperActions {\n getStepState: (path: AbsolutePath) => FormStepState | null;\n setSteps: (steps: ResolvedFormStepObject[]) => void;\n setActiveStep: (\n activeStep: ResolvedFormStepObject | null,\n callListener?: boolean,\n ) => void;\n updateActiveStep: () => void;\n registerStepState: (path: AbsolutePath, state: FormStepState) => void;\n goToStep: (index: number) => Promise<void>;\n}\n\n/** Form stepper store. */\nexport type FormStepperStore = ReturnType<typeof useCreateFormStepperContext>;\n\n/** Form stepper context. */\nexport const FormStepperContext = createContext<FormStepperContextValue | null>(\n null,\n);\n\n/** Options used to create the form stepper context. */\nexport interface UseCreateFormStepperContextOptions extends Pick<\n FormStepperProps,\n | \"defaultActiveStep\"\n | \"activeStep\"\n | \"onActiveStepChange\"\n | \"onStepValidation\"\n | \"skipStepValidationOnForwardNavigation\"\n | \"allowForwardNavigationOnError\"\n | \"preventFocusOnError\"\n> {\n formManager: FormManager;\n basePath: AbsolutePath;\n resolvedSteps: ResolvedFormStepObject[];\n}\n\n/** Hook used to create the form stepper context. */\nexport function useCreateFormStepperContext({\n formManager,\n basePath,\n resolvedSteps,\n defaultActiveStep,\n activeStep,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n}: UseCreateFormStepperContextOptions) {\n const focus = useFocus();\n const setLatestInteraction = useSetLatestInteraction();\n const { activePath, onActivePathChange } = useActivePathContext();\n activeStep ??= activePath;\n const latest = useLatestValues({\n printing: usePrinting(),\n formManager,\n onActivePathChange,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n });\n\n const store = useConstant(() =>\n createStore<FormStepperState>()(\n subscribeWithSelector((set, get) => ({\n steps: resolvedSteps,\n activeStep:\n activeStep === undefined\n ? defaultActiveStep == null\n ? null\n : (resolvedSteps.find((data) =>\n data.path.equals(basePath.resolve(defaultActiveStep)),\n ) ?? null)\n : activeStep === null\n ? null\n : (resolvedSteps.find((data) =>\n data.path.equals(basePath.resolve(activeStep)),\n ) ?? null),\n stepStates: [{}],\n actions: {\n getStepState: (path) => get().stepStates[0][path.toString()] ?? null,\n setSteps: (steps) => {\n const newStepStates: Record<string, FormStepState | null> = {};\n for (const step of steps) {\n newStepStates[step.path.toString()] = get().actions.getStepState(\n step.path,\n );\n }\n set({\n steps,\n stepStates: [newStepStates],\n });\n get().actions.updateActiveStep();\n },\n setActiveStep: (\n step: ResolvedFormStepObject | null,\n callListener = true,\n ) => {\n if (latest.printing) {\n return;\n }\n\n const oldActiveStep = get().activeStep;\n if (\n !oldActiveStep?.path.equals(step?.path) ||\n oldActiveStep?.index !== step?.index\n ) {\n startTransition(() => {\n set({ activeStep: step });\n if (step != null) {\n setLatestInteraction(step.path);\n }\n latest.onActivePathChange(step?.path ?? null);\n if (callListener) {\n latest.onActiveStepChange?.(\n step?.path ?? null,\n step?.index ?? -1,\n );\n }\n });\n }\n },\n updateActiveStep: () => {\n if (\n latest.printing ||\n (get().activeStep !== null &&\n get().steps.some((step) =>\n step.path.equals(get().activeStep!.path),\n ))\n ) {\n return;\n }\n\n get().actions.setActiveStep(\n get().steps[\n Math.max(\n 0,\n Math.min(\n get().activeStep?.index ?? -1,\n get().steps.length - 1,\n ),\n )\n ] ?? null,\n );\n },\n registerStepState: (path, state) => {\n const stepStates = get().stepStates[0];\n stepStates[path.toString()] = state;\n set({ stepStates: [stepStates] });\n get().actions.updateActiveStep();\n },\n goToStep: async (newStepIndex: number) => {\n if (latest.printing) {\n return;\n }\n\n const oldActiveStep = get().activeStep;\n const newActiveStep = get().steps[newStepIndex];\n if (\n (oldActiveStep?.path != newActiveStep?.path &&\n (oldActiveStep?.path == null || newActiveStep?.path == null)) ||\n (oldActiveStep?.path != null &&\n newActiveStep?.path != null &&\n !newActiveStep.path.contains(oldActiveStep.path))\n ) {\n // Mark steps as touched and validate them prior to moving to the\n // following step (when `skipStepValidationOnForwardNavigation` is\n // not set)\n let shouldChangeActiveStep = true;\n if (\n !latest.skipStepValidationOnForwardNavigation &&\n oldActiveStep &&\n newActiveStep &&\n oldActiveStep.index < newActiveStep.index\n ) {\n const touchAndValidateStep = async (i: number) => {\n const stepPathRecursive = get().steps[i].path.append(\n AbsolutePathFragment.RecursiveWildcard,\n );\n await latest.formManager.setTouched(stepPathRecursive);\n const issues =\n await latest.formManager.validate(stepPathRecursive);\n latest.onStepValidation?.(issues);\n return issues;\n };\n\n for (\n let i = oldActiveStep.index;\n i < newActiveStep.index;\n ++i\n ) {\n // Unless `allowForwardNavigationOnError` is set, focus the first\n // error we find after validating the form, and don't allow\n // navigating further\n if (latest.allowForwardNavigationOnError) {\n void touchAndValidateStep(i);\n } else {\n const issues = await touchAndValidateStep(i);\n const firstError = issues.find(\n (issue) => issue.severity === \"error\",\n );\n if (firstError) {\n shouldChangeActiveStep = false;\n if (!latest.preventFocusOnError) {\n setTimeout(() => focus(firstError.path));\n }\n break;\n }\n }\n }\n }\n\n if (shouldChangeActiveStep) {\n get().actions.setActiveStep(newActiveStep);\n }\n }\n },\n },\n })),\n ),\n );\n\n // Update store when params change\n useEffect(() => {\n store.getState().actions.setSteps(resolvedSteps);\n if (activeStep !== undefined) {\n const { steps, activeStep: oldActiveStep } = store.getState();\n const specificPath = mostSpecificPath(\n activeStep === null ? null : basePath.resolve(activeStep),\n steps.map((step) => step.path),\n oldActiveStep?.path ?? null,\n );\n store\n .getState()\n .actions.setActiveStep(\n steps.find((step) => step.path.equals(specificPath)) ?? null,\n false,\n );\n }\n }, [resolvedSteps, activeStep, basePath, store]);\n\n // Set (possibly new) active step when focused path changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n const { steps, activeStep, actions } = store.getState();\n const specificPath = mostSpecificPath(\n focusedPath,\n steps.map((step) => step.path),\n activeStep?.path ?? null,\n );\n actions.setActiveStep(\n steps.find((step) => step.path.equals(specificPath)) ?? null,\n );\n },\n [store],\n ),\n );\n\n return store;\n}\n\nexport function useFormStepperContext(): FormStepperContextValue {\n const formStepperContext = useContext(FormStepperContext);\n if (!formStepperContext) {\n throw new Error(\"Form stepper context not in scope.\");\n }\n return formStepperContext;\n}\n\nexport function useFormStepState<T>(\n path: AbsolutePath,\n selector: (state: FormStepState | null) => T,\n): T {\n return useStore(useFormStepperContext(), (state) =>\n selector(state.actions.getStepState(path)),\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport { CurrentPath, useResolvedPath } from \"@ostack.tech/kform-react\";\nimport {\n cx,\n DocumentTitle,\n ErrorBoundary,\n Spinner,\n StepContent,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n Suspense,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormAppStatus } from \"../FormApp\";\nimport { useFormStepState } from \"./FormStepperContext.ts\";\n\n/** Properties of the form step content component. */\nexport interface FormStepContentProps extends Omit<\n ComponentPropsWithoutRef<typeof StepContent>,\n \"index\" | \"children\"\n> {\n /**\n * Step path. This should match the path of the step provided to\n * `FormStepper`.\n */\n path?: string | Path;\n /** Sets the step as disabled. */\n disabled?: boolean;\n /** Sets the step as read-only. */\n readOnly?: boolean;\n /** Properties to pass to the `ErrorBoundary` component. */\n errorBoundaryProps?: ComponentPropsWithRef<typeof ErrorBoundary>;\n children?: ReactNode;\n}\n\n/** Component containing the content of a form step. */\nexport const FormStepContent = forwardRef<\n ComponentRef<typeof StepContent>,\n FormStepContentProps\n>(function FormStepContent(\n {\n path,\n disabled = false,\n readOnly = false,\n errorBoundaryProps,\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const stepPath = useResolvedPath(path);\n const index = useFormStepState(stepPath, (controller) => controller?.index);\n const documentTitle = useFormStepState(stepPath, (state) =>\n state === null ? null : state.documentTitle,\n );\n\n if (documentTitle === undefined) {\n warnOnce(\n `FormStep: At '${stepPath.toString()}': \\`documentTitle\\` ` +\n \"should be set manually since the form step's `title` is not a string.\",\n );\n }\n\n return (\n index != null && (\n <CurrentPath path={stepPath}>\n <StepContent\n index={index}\n className={cx(prefix(\"form-stepper__step-content\"), className)}\n {...otherProps}\n ref={forwardedRef}\n >\n <DocumentTitle title={documentTitle ?? undefined}>\n <FormAppStatus disabled={disabled} readOnly={readOnly}>\n <ErrorBoundary {...errorBoundaryProps}>\n <Suspense fallback={<Spinner size=\"xl\" color=\"primary\" />}>\n {children}\n </Suspense>\n </ErrorBoundary>\n </FormAppStatus>\n </DocumentTitle>\n </StepContent>\n </CurrentPath>\n )\n );\n});\n","import type { AbsolutePath } from \"@ostack.tech/kform\";\nimport { CurrentPath } from \"@ostack.tech/kform-react\";\nimport { Step } from \"@ostack.tech/ui\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useFormStepState } from \"./FormStepperContext.ts\";\n\n/** Properties of the form step component. */\nexport interface FormStepProps {\n path: AbsolutePath;\n index: number;\n}\n\n/** Form step. */\nexport function FormStep({ path, index }: FormStepProps) {\n const prefix = usePrefix();\n const deferredDisplayStatus = useFormStepState(\n path,\n (state) => state?.deferredDisplayStatus,\n );\n const disabled = useFormStepState(path, (state) => !state?.exists);\n const title = useFormStepState(path, (state) => state?.title);\n\n return (\n <Step\n index={index}\n status={displayStatusToControlStatus(deferredDisplayStatus)}\n disabled={disabled}\n className={prefix(\"form-stepper__step\")}\n >\n <CurrentPath path={path}>{title}</CurrentPath>\n </Step>\n );\n}\n","import { cx, StepList } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { FormStep } from \"./FormStep.tsx\";\nimport { useFormStepperContext } from \"./FormStepperContext.ts\";\n\n/** Properties of the form steps sidebar component. */\nexport interface FormStepListProps extends ComponentPropsWithoutRef<\n typeof StepList\n> {}\n\n/** Component displaying all form steps in a list. */\nexport const FormStepList = forwardRef<\n ComponentRef<typeof StepList>,\n FormStepListProps\n>(function FormStepperSidebar({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n const steps = useStore(useFormStepperContext(), (state) => state.steps);\n\n return (\n <StepList\n className={cx(prefix(\"form-stepper__step-list\"), className)}\n {...otherProps}\n ref={forwardedRef}\n >\n {steps.map((step) => (\n <FormStep\n key={step.path.toString()}\n path={step.path}\n index={step.index}\n />\n ))}\n </StepList>\n );\n});\n","import { CurrentPath, useController } from \"@ostack.tech/kform-react\";\nimport { usePrinting } from \"@ostack.tech/ui\";\nimport { useDeferredValue, useEffect } from \"react\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport {\n type ResolvedFormStepObject,\n useFormStepperContext,\n} from \"./FormStepperContext.ts\";\n\n/** Properties of the `FormStepRegistrar` component. */\nexport interface FormStepRegistrarProps extends ResolvedFormStepObject {}\n\n/** Component used to register a form step. */\nexport function FormStepRegistrar({\n index,\n path,\n title,\n documentTitle,\n issuesPanelLabel,\n}: FormStepRegistrarProps) {\n const store = useFormStepperContext();\n\n const printing = usePrinting();\n const controller = useController(path, { enabled: !useFormIsLoading() });\n const absolutePath = controller.usePath();\n const exists = controller.useState(\n (state) => state.initialized && state.exists,\n );\n const value = controller.useValue();\n const deferredValue = useDeferredValue(value);\n const relevantValue = printing ? value : deferredValue;\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n\n const actualTitle =\n typeof title === \"function\"\n ? relevantValue === undefined\n ? null\n : title(relevantValue)\n : title;\n const actualDocumentTitle =\n typeof documentTitle === \"function\"\n ? relevantValue === undefined\n ? null\n : documentTitle(relevantValue)\n : documentTitle === undefined\n ? actualTitle === null || typeof actualTitle === \"string\"\n ? actualTitle\n : undefined\n : documentTitle;\n\n useEffect(() => {\n const { registerStepState } = store.getState().actions;\n registerStepState(absolutePath, {\n exists,\n path: absolutePath,\n deferredDisplayStatus,\n index,\n title: actualTitle,\n documentTitle: actualDocumentTitle,\n });\n }, [\n absolutePath,\n actualDocumentTitle,\n actualTitle,\n deferredDisplayStatus,\n exists,\n index,\n store,\n title,\n ]);\n\n useRegisterController(controller);\n useRegisterLabel(\n absolutePath,\n <CurrentPath path={absolutePath}>\n {typeof issuesPanelLabel === \"function\"\n ? deferredValue === undefined\n ? null\n : issuesPanelLabel(deferredValue)\n : issuesPanelLabel || actualTitle}\n </CurrentPath>,\n );\n\n return null;\n}\n","import {\n type AbsolutePath,\n AbsolutePathFragment,\n Path,\n type SealedLocatedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport {\n CurrentPath,\n useFormManager,\n useResolvedPath,\n} from \"@ostack.tech/kform-react\";\nimport { cx, Stepper } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { useStore } from \"zustand\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport {\n FormStepperContext,\n useCreateFormStepperContext,\n} from \"./FormStepperContext.ts\";\nimport { FormStepRegistrar } from \"./FormStepRegistrar.tsx\";\n\n/** Properties of the form stepper component. */\nexport interface FormStepperProps extends Omit<\n ComponentPropsWithoutRef<typeof Stepper>,\n \"defaultActiveStep\" | \"activeStep\" | \"onActiveStepChange\"\n> {\n /** Base path for all declared form steps. */\n path?: string | Path;\n /** List of all form steps. */\n steps: FormStepObject[];\n /** Default active form step. */\n defaultActiveStep?: string | Path;\n /** Controlled active form step. */\n activeStep?: string | Path;\n /**\n * Function called whenever the active form step changes.\n *\n * @param activeStepPath Path of the new active form step.\n * @param activeStepIndex Index of the new active form step.\n */\n onActiveStepChange?: (\n activeStepPath: AbsolutePath | null,\n activeStepIndex: number,\n ) => void;\n /**\n * Function called when a step is touched and validated due to a navigation to\n * a following step. This function is never called when\n * `skipStepValidationOnForwardNavigation` is `true`.\n *\n * @param issues Issues present in the step.\n */\n onStepValidation?: (issues: SealedLocatedValidationIssue[]) => void;\n /**\n * Whether to skip marking a step as touched and validating it when navigating\n * to a following step.\n *\n * @default false\n */\n skipStepValidationOnForwardNavigation?: boolean;\n /**\n * Whether to allow navigation to a following step when a previous step\n * contains errors. This is always `true` when\n * `skipStepValidationOnForwardNavigation` is also `true`.\n *\n * @default false\n */\n allowForwardNavigationOnError?: boolean;\n /**\n * Whether to prevent the focus of an invalid field when a step was validated\n * and an error was found. This is always `true` if either\n * `skipStepValidationOnForwardNavigation` or `allowForwardNavigationOnError`\n * are `true`.\n *\n * @default false\n */\n preventFocusOnError?: boolean;\n}\n\n/** Object representation of a form step. */\nexport interface FormStepObject<T = any> {\n /** Form step path. */\n path?: string | Path;\n /** Form step's title. */\n title: ReactNode | ((value: T) => ReactNode);\n /**\n * Title of the form step as a string to display in the document's title.\n *\n * Defaults to `title` when it is a string. A warning is printed if `title` is\n * not a string and `documentTitle` is not provided.\n */\n documentTitle?: string | null | ((value: T) => string | null);\n /** Label of the form step in the issues panel. Uses the `title` by default. */\n issuesPanelLabel?: ReactNode | ((value: T) => ReactNode);\n}\n\n/** Root component used to render form steps. */\nexport const FormStepper = forwardRef<\n ComponentRef<typeof Stepper>,\n FormStepperProps\n>(function FormStepper(\n {\n path,\n steps,\n defaultActiveStep,\n activeStep,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const formManager = useFormManager();\n const absolutePath = useResolvedPath(path);\n\n // Provided steps but with absolute paths and indices\n const resolvedSteps = useMemo(\n () =>\n steps.map((step, i) => ({\n ...step,\n index: i,\n path: absolutePath.resolve(step.path ?? Path.CURRENT),\n })),\n [absolutePath, steps],\n );\n\n // Refuse non-existent paths\n if (!formManager.isValidPath(absolutePath)) {\n throw new Error(`Invalid path: '${absolutePath.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n absolutePath.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form stepper base path must only contain ids.\");\n }\n // Validate form step paths\n for (const step of resolvedSteps) {\n // Refuse non-existent paths\n if (!formManager.isValidPath(step.path)) {\n throw new Error(`Invalid path: '${step.path.toString()}'`);\n }\n // Refuse paths that don't consist of identifiers only\n if (\n step.path.fragments.some(\n (frag) => !(frag instanceof AbsolutePathFragment.Id),\n )\n ) {\n throw new Error(\"Form step path must only contain ids.\");\n }\n }\n\n const store = useCreateFormStepperContext({\n formManager,\n basePath: absolutePath,\n resolvedSteps,\n defaultActiveStep,\n activeStep,\n onActiveStepChange,\n onStepValidation,\n skipStepValidationOnForwardNavigation,\n allowForwardNavigationOnError,\n preventFocusOnError,\n });\n const activeIndex = useStore(store, (state) => state.activeStep?.index ?? -1);\n const { goToStep } = useStore(store, (state) => state.actions);\n\n return (\n <CurrentPath path={absolutePath}>\n <FormStepperContext.Provider value={store}>\n {resolvedSteps.map((step) => (\n <FormStepRegistrar key={step.path.toString()} {...step} />\n ))}\n\n <Stepper\n className={cx(prefix(\"form-stepper\"), className)}\n activeStep={activeIndex}\n onActiveStepChange={goToStep}\n {...otherProps}\n ref={forwardedRef}\n />\n </FormStepperContext.Provider>\n </CurrentPath>\n );\n});\n","import type { Path, ValidationIssueData } from \"@ostack.tech/kform\";\nimport { useIssuesTracker } from \"@ostack.tech/kform-react\";\nimport { Alert } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\n\n/** Properties of the issue alert component. */\nexport interface IssueAlertProps extends Omit<\n ComponentPropsWithoutRef<typeof Alert>,\n \"severity\" | \"children\"\n> {\n /** Path of the value with the issue in question. */\n path?: string | Path;\n /** Code of the issue in question. */\n code: string;\n children?: ReactNode | ((issueData: ValidationIssueData) => ReactNode);\n}\n\n/** Component used to display an issue alert. */\nexport const IssueAlert = forwardRef<\n ComponentRef<typeof Alert>,\n IssueAlertProps\n>(function IssueMessage({ path, code, children, ...otherProps }, forwardedRef) {\n const { info } = useIssuesTracker(path);\n const relevantIssues = (info?.flatMap((info) => info.issues) ?? []).filter(\n (issue) => issue.code === code,\n );\n\n return (\n <>\n {relevantIssues.map((issue, i) => (\n <Alert\n {...otherProps}\n severity={issue.severity === \"error\" ? \"danger\" : \"warning\"}\n ref={forwardedRef}\n key={i}\n >\n {typeof children === \"function\"\n ? children(issue.data ?? {})\n : children}\n </Alert>\n ))}\n </>\n );\n});\n","import { useFormController } from \"@ostack.tech/kform-react\";\nimport { useCallback, useMemo } from \"react\";\n\nimport { useStartIssuesNavigation } from \"../components/FormApp\";\n\n/** Result of the {@link useFormValidator} hook. */\nexport interface FormValidatorResult {\n /**\n * Function used to validate the form.\n *\n * @returns Promise which resolves once the form has been validated.\n */\n validate: () => Promise<void>;\n}\n\n/** Hook exposing a function used to validate the form. */\nexport function useFormValidator(): FormValidatorResult {\n const startIssuesNavigation = useStartIssuesNavigation();\n const { _setState } = useFormController();\n\n const validate = useCallback(async () => {\n _setState({ validating: true } as any);\n try {\n await startIssuesNavigation();\n } finally {\n _setState({ validating: false } as any);\n }\n }, [_setState, startIssuesNavigation]);\n\n return useMemo(() => ({ validate }), [validate]);\n}\n\n/** Result of the {@link useFormIsValidating} hook. */\nexport interface FormIsValidatingResult {\n /**\n * Whether form is being validated automatically (due to validating mode being\n * set to `\"auto\"`).\n */\n validatingAutomatically: boolean;\n /**\n * Whether form is being validated manually (due to an explicit `validate`\n * call).\n */\n validatingManually: boolean;\n /** Whether form is being validated (either automatically or manually). */\n validating: boolean;\n}\n\n/** Hook exposing whether the form is currently being validated. */\nexport function useFormIsValidating(): FormIsValidatingResult {\n const validatingAutomatically =\n useFormController().useAutoValidationStatus() === \"activeRunning\";\n const validatingManually = useFormController().useState(\n (state) => (state as any).validating,\n );\n\n return useMemo(\n () => ({\n validatingAutomatically,\n validatingManually,\n validating: validatingAutomatically || validatingManually,\n }),\n [validatingAutomatically, validatingManually],\n );\n}\n","import {\n faAngleLeft,\n faAngleRight,\n faAnglesLeft,\n faAnglesRight,\n faArrowsToDot,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport type { AbsolutePath } from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport {\n CloseButton,\n combineEventHandlers,\n cx,\n IconButton,\n type IconButtonColor,\n Spinner,\n VisuallyHidden,\n} from \"@ostack.tech/ui\";\nimport { useDeferredValue } from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsValidating } from \"../../utils/useFormValidator.ts\";\nimport { useFocus } from \"../FormApp\";\nimport type { IssuesPanelProps } from \"./IssuesPanel.tsx\";\n\n/** Properties of the issues panel controls component. */\nexport interface IssuesPanelControlsProps extends Pick<\n IssuesPanelProps,\n | \"focusButtonLabel\"\n | \"previousIssueButtonLabel\"\n | \"nextIssueButtonLabel\"\n | \"firstIssueButtonLabel\"\n | \"lastIssueButtonLabel\"\n | \"paginationLabel\"\n | \"validatingSpinnerProps\"\n | \"paginationProps\"\n | \"focusButtonProps\"\n | \"previousIssueButtonProps\"\n | \"nextIssueButtonProps\"\n | \"firstIssueButtonProps\"\n | \"lastIssueButtonProps\"\n | \"closeButtonProps\"\n> {\n currentPagePath: AbsolutePath | null;\n currentPageIndex: number;\n currentPageController: Controller;\n nPages: number;\n goToPreviousPage: () => void;\n goToNextPage: () => void;\n goToFirstPage: () => void;\n goToLastPage: () => void;\n buttonsColor?: IconButtonColor;\n closePanel: () => void;\n}\n\n/** Controls of the issues panel. */\nexport function IssuesPanelControls({\n currentPagePath,\n nPages,\n currentPageIndex,\n currentPageController,\n goToPreviousPage,\n goToNextPage,\n goToFirstPage,\n goToLastPage,\n buttonsColor,\n closePanel,\n focusButtonLabel,\n previousIssueButtonLabel,\n nextIssueButtonLabel,\n firstIssueButtonLabel,\n lastIssueButtonLabel,\n paginationLabel,\n validatingSpinnerProps,\n paginationProps,\n focusButtonProps,\n previousIssueButtonProps,\n nextIssueButtonProps,\n firstIssueButtonProps,\n lastIssueButtonProps,\n closeButtonProps,\n}: IssuesPanelControlsProps) {\n const prefix = usePrefix();\n const { validating } = useFormIsValidating();\n const deferredValidating = useDeferredValue(validating);\n const currentPageInitialized = currentPageController.useInitialized();\n const currentPageExists = currentPageController.useExists();\n\n const focus = useFocus();\n\n return (\n <div className={prefix(\"issues-panel__controls\")}>\n {nPages > 0 && (\n <>\n {/* Validating spinner. */}\n {deferredValidating && (\n <Spinner\n {...validatingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__validating-spinner\"),\n validatingSpinnerProps?.className,\n )}\n />\n )}\n\n {/* Pagination. */}\n <div\n role=\"presentation\"\n aria-live=\"polite\"\n {...paginationProps}\n className={cx(\n prefix(\"issues-panel__pagination\"),\n paginationProps?.className,\n )}\n >\n {paginationLabel && currentPageIndex !== -1 && (\n <VisuallyHidden>\n {paginationLabel(currentPageIndex + 1, nPages)}\n </VisuallyHidden>\n )}\n <span aria-hidden=\"true\">\n {currentPageIndex === -1 ? \"-\" : currentPageIndex + 1} / {nPages}\n </span>\n </div>\n\n {/* Focus button. */}\n <IconButton\n color={buttonsColor}\n icon={faArrowsToDot}\n {...focusButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__focus\"),\n focusButtonProps?.className,\n )}\n label={focusButtonLabel ?? \"\"}\n loading={!currentPageInitialized}\n disabled={!currentPageExists}\n onClick={combineEventHandlers(focusButtonProps?.onClick, () =>\n focus(currentPagePath!),\n )}\n />\n\n {/* First issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAnglesLeft}\n {...firstIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__first\"),\n firstIssueButtonProps?.className,\n )}\n label={firstIssueButtonLabel ?? \"\"}\n disabled={firstIssueButtonProps?.disabled || currentPageIndex === 0}\n onClick={combineEventHandlers(\n firstIssueButtonProps?.onClick,\n goToFirstPage,\n )}\n />\n\n {/* Previous issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAngleLeft}\n {...previousIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__previous\"),\n previousIssueButtonProps?.className,\n )}\n label={previousIssueButtonLabel ?? \"\"}\n disabled={\n previousIssueButtonProps?.disabled || currentPageIndex === 0\n }\n onClick={combineEventHandlers(\n previousIssueButtonProps?.onClick,\n goToPreviousPage,\n )}\n />\n\n {/* Next issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAngleRight}\n {...nextIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__next\"),\n nextIssueButtonProps?.className,\n )}\n label={nextIssueButtonLabel ?? \"\"}\n disabled={\n nextIssueButtonProps?.disabled || currentPageIndex === nPages - 1\n }\n onClick={combineEventHandlers(\n nextIssueButtonProps?.onClick,\n goToNextPage,\n )}\n />\n\n {/* Last issue button. */}\n <IconButton\n color={buttonsColor}\n icon={faAnglesRight}\n {...lastIssueButtonProps}\n className={cx(\n prefix(\"issues-panel__action\"),\n prefix(\"issues-panel__last\"),\n lastIssueButtonProps?.className,\n )}\n label={lastIssueButtonLabel ?? \"\"}\n disabled={\n lastIssueButtonProps?.disabled || currentPageIndex === nPages - 1\n }\n onClick={combineEventHandlers(\n lastIssueButtonProps?.onClick,\n goToLastPage,\n )}\n />\n </>\n )}\n\n {/* Close button. */}\n <CloseButton\n color={buttonsColor}\n {...closeButtonProps}\n className={cx(\n prefix(\"issues-panel__close-button\"),\n closeButtonProps?.className,\n )}\n onClick={combineEventHandlers(closeButtonProps?.onClick, closePanel, {\n checkDefaultPrevented: true,\n })}\n />\n </div>\n );\n}\n","import {\n faCircleCheck,\n faCircleExclamation,\n faTriangleExclamation,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport type { AbsolutePath, ValidationIssueSeverity } from \"@ostack.tech/kform\";\nimport {\n type Controller,\n CurrentPath,\n type IssuesTrackerResult,\n useFormManager,\n} from \"@ostack.tech/kform-react\";\nimport {\n Card,\n CardBody,\n CardHeader,\n CardTitle,\n cx,\n Icon,\n type IconButtonColor,\n setBoolDataAttr,\n Spinner,\n useCombinedRef,\n useScrollPosition,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useActiveIssuesPanelBreadcrumb, useIsRegistered } from \"../FormApp\";\nimport { IssueMessage } from \"../IssueMessage\";\nimport type { IssuesPanelProps } from \"./IssuesPanel.tsx\";\n\nexport interface IssuesPanelMessagesCardProps\n extends\n ComponentPropsWithoutRef<typeof Card>,\n Pick<\n IssuesPanelProps,\n | \"displayIssueCodes\"\n | \"unknownErrorMessage\"\n | \"unknownWarningMessage\"\n | \"errorsLabel\"\n | \"warningsLabel\"\n | \"noIssuesMessage\"\n | \"resolvedTitle\"\n | \"resolvedMessage\"\n | \"headerProps\"\n | \"bodyProps\"\n | \"loadingSpinnerProps\"\n | \"titleProps\"\n | \"iconProps\"\n > {\n currentPagePath: AbsolutePath | null;\n currentPageController: Controller;\n issuesTrackerResult: IssuesTrackerResult;\n currentPageIndex: number;\n renderControls: (buttonsColor?: IconButtonColor) => ReactNode;\n}\n\nexport const IssuesPanelMessagesCard = forwardRef<\n ComponentRef<typeof Card>,\n IssuesPanelMessagesCardProps\n>(function IssuesPanelMessagesCard(\n {\n currentPagePath,\n currentPageController,\n issuesTrackerResult,\n currentPageIndex,\n errorsLabel,\n warningsLabel,\n noIssuesMessage,\n resolvedTitle,\n resolvedMessage,\n displayIssueCodes,\n unknownErrorMessage,\n unknownWarningMessage,\n renderControls,\n headerProps,\n bodyProps,\n loadingSpinnerProps,\n titleProps,\n iconProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { initialized, info } = issuesTrackerResult;\n const nPages = info?.length ?? 0;\n const currentInfo = currentPageIndex === -1 ? null : info![currentPageIndex];\n const currentPageExists = currentPageController.useExists();\n\n // Relevant icon and colour\n const relevantIcon = initialized\n ? !currentInfo\n ? faCircleCheck\n : currentInfo.localDisplayStatus === \"error\"\n ? faCircleExclamation\n : faTriangleExclamation\n : undefined;\n const relevantColor = initialized\n ? nPages === 0\n ? \"success\"\n : !currentInfo\n ? \"primary\"\n : currentInfo.localDisplayStatus === \"error\"\n ? \"danger\"\n : \"warning\"\n : undefined;\n\n const hasErrors = currentInfo?.localDisplayStatus === \"error\";\n const hasWarnings =\n currentInfo?.localDisplayStatus === \"warning\" ||\n (currentInfo?.localDisplayStatus === \"error\" &&\n currentInfo.issues.some((issue) => issue.severity === \"warning\"));\n\n const formManager = useFormManager();\n const schema = useMemo(\n () => currentInfo && formManager.schema(currentInfo.path),\n [currentInfo, formManager],\n );\n\n // Whether the active issues panel path has been registered at all\n const isRegistered = useIsRegistered(currentPagePath);\n const lastRegisteredPath = useRef<AbsolutePath | null>(null);\n if (isRegistered) {\n lastRegisteredPath.current = currentPagePath;\n }\n const hasBeenRegistered =\n isRegistered || lastRegisteredPath?.current?.equals(currentPagePath);\n\n // Sticky style for card header\n const [cardEl, setCardEl] = useState<HTMLDivElement | null>(null);\n const headerRef = useRef<HTMLDivElement | null>(null);\n useScrollPosition(\n cardEl,\n useCallback(\n (scrollPosition) =>\n setBoolDataAttr(\n headerRef.current,\n \"stuck\",\n (scrollPosition?.top ?? 0) > 0,\n ),\n [],\n ),\n );\n\n const renderIssuesList = (severity: ValidationIssueSeverity) =>\n (severity === \"error\" ? hasErrors : hasWarnings) && (\n <>\n <h3 className={prefix(\"issues-panel__issues-list-title\")}>\n {severity === \"error\" ? errorsLabel?.() : warningsLabel?.()}\n </h3>\n\n <ul className={prefix(\"issues-panel__issues-list\")}>\n {currentInfo!.issues\n .filter((issue) => issue.severity === severity)\n .map((issue, i) => (\n <li\n key={i}\n className={prefix(\"issues-panel__issue\")}\n data-severity={issue.severity}\n >\n <IssueMessage\n path={currentInfo!.path}\n issue={issue}\n schema={schema!}\n displayIssueCode={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n issueCodeProps={{\n className: prefix(\"issues-panel__issue-code\"),\n }}\n />\n </li>\n ))}\n </ul>\n </>\n );\n\n const combinedCardRef = useCombinedRef(setCardEl, forwardedRef);\n const combinedHeaderRef = useCombinedRef(headerRef, headerProps?.ref);\n return (\n <Card\n variant=\"subtle\"\n mergeSections\n className={cx(\n prefix(\"issues-panel\"),\n prefix(\"issues-panel--messages\"),\n className,\n )}\n {...otherProps}\n color={relevantColor ?? \"neutral\"}\n ref={combinedCardRef}\n >\n <CardHeader\n {...headerProps}\n className={cx(prefix(\"issues-panel__header\"), headerProps?.className)}\n ref={combinedHeaderRef}\n >\n {renderControls(relevantColor ?? \"primary\")}\n\n {/* Initialisation spinner. */}\n {!initialized && (\n <Spinner\n size=\"lg\"\n {...loadingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__loading-spinner\"),\n loadingSpinnerProps?.className,\n )}\n />\n )}\n\n {initialized && (\n <>\n {/* Panel icon. */}\n <Icon\n color={relevantColor}\n size=\"lg\"\n {...iconProps}\n className={cx(prefix(\"issues-panel__icon\"), iconProps?.className)}\n icon={relevantIcon!}\n />\n\n <CardTitle\n role=\"presentation\"\n aria-live=\"polite\"\n {...titleProps}\n className={cx(\n prefix(\"issues-panel__title\"),\n titleProps?.className,\n )}\n >\n {nPages === 0 ? (\n noIssuesMessage\n ) : hasBeenRegistered ? (\n currentPageExists ? (\n <Breadcrumb />\n ) : (\n resolvedTitle\n )\n ) : (\n <Spinner\n size=\"lg\"\n {...loadingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__loading-spinner\"),\n loadingSpinnerProps?.className,\n )}\n />\n )}\n </CardTitle>\n </>\n )}\n </CardHeader>\n\n <CardBody\n {...bodyProps}\n className={cx(prefix(\"issues-panel__body\"), bodyProps?.className)}\n >\n {currentInfo && hasBeenRegistered && renderIssuesList(\"error\")}\n {currentInfo && hasBeenRegistered && renderIssuesList(\"warning\")}\n {!currentInfo && nPages > 0 && (\n <div className={prefix(\"issues-panel__resolved-message\")}>\n {resolvedMessage}\n </div>\n )}\n </CardBody>\n </Card>\n );\n});\n\nfunction Breadcrumb() {\n const prefix = usePrefix();\n const breadcrumb = useActiveIssuesPanelBreadcrumb();\n\n return (\n breadcrumb &&\n (breadcrumb.length === 1 ? breadcrumb : breadcrumb.slice(1)).map(\n ({ path, label }) => (\n <CurrentPath key={path.toString()} path={path}>\n <span className={prefix(\"issues-panel__breadcrumb-item\")}>\n {label}\n </span>\n </CurrentPath>\n ),\n )\n );\n}\n","import {\n faCircleCheck,\n faCircleExclamation,\n faTriangleExclamation,\n} from \"@fortawesome/free-solid-svg-icons\";\nimport type { IssuesTrackerResult } from \"@ostack.tech/kform-react\";\nimport {\n Card,\n CardHeader,\n CardTitle,\n cx,\n Icon,\n type IconButtonColor,\n Spinner,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport type { IssuesPanelProps } from \"./IssuesPanel.tsx\";\n\nexport interface IssuesPanelSummaryCardProps\n extends\n ComponentPropsWithoutRef<typeof Card>,\n Pick<\n IssuesPanelProps,\n | \"errorsLabel\"\n | \"warningsLabel\"\n | \"noIssuesMessage\"\n | \"headerProps\"\n | \"loadingSpinnerProps\"\n | \"titleProps\"\n | \"iconProps\"\n > {\n issuesTrackerResult: IssuesTrackerResult;\n renderControls: (buttonsColor?: IconButtonColor) => ReactNode;\n}\n\nexport const IssuesPanelSummaryCard = forwardRef<\n ComponentRef<typeof Card>,\n IssuesPanelSummaryCardProps\n>(function IssuesPanelSummaryCard(\n {\n issuesTrackerResult,\n errorsLabel,\n warningsLabel,\n noIssuesMessage,\n renderControls,\n headerProps,\n loadingSpinnerProps,\n titleProps,\n iconProps,\n className,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { initialized, info, errors, warnings } = issuesTrackerResult;\n const nPages = info?.length ?? 0;\n\n // Relevant icon and colour\n const relevantIcon = initialized\n ? errors > 0\n ? faCircleExclamation\n : warnings > 0\n ? faTriangleExclamation\n : faCircleCheck\n : undefined;\n const relevantColor = initialized\n ? errors > 0\n ? \"danger\"\n : warnings > 0\n ? \"warning\"\n : \"success\"\n : undefined;\n\n return (\n <Card\n variant=\"subtle\"\n mergeSections\n className={cx(\n prefix(\"issues-panel\"),\n prefix(\"issues-panel--summary\"),\n className,\n )}\n {...otherProps}\n color={initialized ? relevantColor : \"neutral\"}\n ref={forwardedRef}\n >\n <CardHeader\n {...headerProps}\n className={cx(prefix(\"issues-panel__header\"), headerProps?.className)}\n >\n {/* Initialisation spinner. */}\n {!initialized && (\n <Spinner\n size=\"lg\"\n {...loadingSpinnerProps}\n className={cx(\n prefix(\"issues-panel__loading-spinner\"),\n loadingSpinnerProps?.className,\n )}\n />\n )}\n\n {initialized && (\n <>\n {/* Panel icon. */}\n <Icon\n color={relevantColor}\n size=\"lg\"\n {...iconProps}\n className={cx(prefix(\"issues-panel__icon\"), iconProps?.className)}\n icon={relevantIcon!}\n />\n\n <CardTitle\n role=\"presentation\"\n aria-live=\"polite\"\n {...titleProps}\n className={cx(\n prefix(\"issues-panel__title\"),\n titleProps?.className,\n )}\n >\n {nPages === 0 && noIssuesMessage}\n {nPages > 0 && (\n <>\n {errors > 0 && errorsLabel?.(errors)}\n {errors > 0 && warnings > 0 && \", \"}\n {warnings > 0 && warningsLabel?.(warnings)}\n </>\n )}\n </CardTitle>\n </>\n )}\n\n {renderControls(relevantColor)}\n </CardHeader>\n </Card>\n );\n});\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n compareSchemaPaths,\n type Schema,\n} from \"@ostack.tech/kform\";\nimport {\n type IssuesTrackerOptions,\n type LocatedValidationInfo,\n useController,\n useFormManager,\n useIssuesTracker,\n} from \"@ostack.tech/kform-react\";\nimport {\n type Card,\n type CardBody,\n type CardHeader,\n type CardTitle,\n type CloseButton,\n Container,\n cx,\n type Icon,\n type IconButton,\n type IconButtonColor,\n setBoolDataAttr,\n type Spinner,\n useCombinedRef,\n useControllableState,\n useIntersectionObserver,\n useLatestValues,\n useMeasure,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useDeferredValue,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useReportValidationFailures } from \"../../utils/useReportValidationFailures.ts\";\nimport {\n useFocus,\n useFormAppElement,\n useIssuesDisplayMode,\n useSetBottomPanelHeight,\n} from \"../FormApp\";\nimport {\n useIssuesPanelPath,\n useLatestInteraction,\n useSetStartIssuesNavigation,\n} from \"../FormApp/FormAppContext.ts\";\nimport { IssuesPanelControls } from \"./IssuesPanelControls.tsx\";\nimport { IssuesPanelMessagesCard } from \"./IssuesPanelMessagesCard.tsx\";\nimport { IssuesPanelSummaryCard } from \"./IssuesPanelSummaryCard.tsx\";\n\n/** Properties of the issues navigation component. */\nexport interface IssuesPanelProps\n extends\n Pick<IssuesTrackerOptions, \"issuesOrderCompareFn\">,\n Omit<\n ComponentPropsWithoutRef<typeof Card>,\n \"children\" | \"variant\" | \"color\"\n > {\n /** Default open state of the issues navigation panel. */\n defaultOpen?: boolean;\n /** Controlled open state of the issues navigation panel. */\n open?: boolean;\n /**\n * Function called whenever the open state of the issues navigation panel\n * changes.\n *\n * @param open New open state.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Whether to display issue codes together with each issue message.\n *\n * This property can also be set globally via the `displayIssueCodes` property\n * of the `FormApp`.\n */\n displayIssueCodes?: boolean;\n /**\n * Message to show for an error that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownErrorMessage?: ReactNode;\n /**\n * Message to show for a warning that does not have an associated message.\n *\n * This message will always automatically include the code of the issue in\n * question.\n */\n unknownWarningMessage?: ReactNode;\n /**\n * Errors label.\n *\n * @param errors Number of errors. If undefined, the function should return a\n * generic label with no number.\n */\n errorsLabel?: (errors?: number) => ReactNode;\n /**\n * Warnings label.\n *\n * @param warnings Number of warnings. If undefined, the function should\n * return a generic label with no number.\n */\n warningsLabel?: (warnings?: number) => ReactNode;\n /** Label of the focus button. */\n focusButtonLabel?: string;\n /** Label of the \"previous issue\" button. */\n previousIssueButtonLabel?: string;\n /** Label of the \"next issue\" button. */\n nextIssueButtonLabel?: string;\n /** Label of the \"first issue\" button. */\n firstIssueButtonLabel?: string;\n /** Label of the \"last issue\" button. */\n lastIssueButtonLabel?: string;\n /**\n * Text announced to assistive technologies with the current page out of the\n * total number of pages.\n *\n * @param currentPage Current page.\n * @param totalPages Total number of pages.\n */\n paginationLabel?: (currentPage: number, totalPages: number) => ReactNode;\n /** Message to display when there are no issues to report. */\n noIssuesMessage?: ReactNode;\n /** Title to display when all issues of the active path have been resolved. */\n resolvedTitle?: ReactNode;\n /** Message to display when all issues of the active path have been resolved. */\n resolvedMessage?: ReactNode;\n /** Properties to pass to the container element. */\n containerProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the card header component. */\n headerProps?: ComponentPropsWithRef<typeof CardHeader>;\n /** Properties to pass to the card body component. */\n bodyProps?: ComponentPropsWithRef<typeof CardBody>;\n /** Properties to pass to the loading `Spinner` component. */\n loadingSpinnerProps?: ComponentPropsWithRef<typeof Spinner>;\n /** Properties to pass to the validating `Spinner` component. */\n validatingSpinnerProps?: ComponentPropsWithRef<typeof Spinner>;\n /** Properties to pass to the pagination element. */\n paginationProps?: ComponentPropsWithRef<\"div\">;\n /** Properties to pass to the \"focus\" button component. */\n focusButtonProps?: Omit<ComponentPropsWithRef<typeof IconButton>, \"label\">;\n /** Properties to pass to the \"previous issue\" button component. */\n previousIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the \"next issue\" button component. */\n nextIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the \"first issue\" button component. */\n firstIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the \"last issue\" button component. */\n lastIssueButtonProps?: Omit<\n ComponentPropsWithRef<typeof IconButton>,\n \"label\"\n >;\n /** Properties to pass to the icon component. */\n iconProps?: Omit<ComponentPropsWithRef<typeof Icon>, \"icon\">;\n /** Properties to pass to the title component. */\n titleProps?: ComponentPropsWithRef<typeof CardTitle>;\n /** Properties to pass to the close button component. */\n closeButtonProps?: ComponentPropsWithRef<typeof CloseButton>;\n}\n\n/** Component used to navigate through the issues of the form. */\nexport const IssuesPanel = forwardRef<\n ComponentRef<typeof Card>,\n IssuesPanelProps\n>(function ValidationPanel(\n {\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n displayIssueCodes,\n issuesOrderCompareFn,\n unknownErrorMessage,\n unknownWarningMessage,\n errorsLabel,\n warningsLabel,\n focusButtonLabel,\n previousIssueButtonLabel,\n nextIssueButtonLabel,\n firstIssueButtonLabel,\n lastIssueButtonLabel,\n paginationLabel,\n noIssuesMessage,\n resolvedTitle,\n resolvedMessage,\n containerProps,\n headerProps,\n bodyProps,\n loadingSpinnerProps,\n validatingSpinnerProps,\n paginationProps,\n focusButtonProps,\n previousIssueButtonProps,\n nextIssueButtonProps,\n firstIssueButtonProps,\n lastIssueButtonProps,\n titleProps,\n iconProps,\n closeButtonProps,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const printing = usePrinting();\n const [locale] = useLocale();\n errorsLabel ??= locale.IssuesPanel.errorsLabel;\n warningsLabel ??= locale.IssuesPanel.warningsLabel;\n focusButtonLabel ??= locale.IssuesPanel.focusButtonLabel;\n previousIssueButtonLabel ??= locale.IssuesPanel.previousIssueButtonLabel;\n nextIssueButtonLabel ??= locale.IssuesPanel.nextIssueButtonLabel;\n firstIssueButtonLabel ??= locale.IssuesPanel.firstIssueButtonLabel;\n lastIssueButtonLabel ??= locale.IssuesPanel.lastIssueButtonLabel;\n paginationLabel ??= locale.IssuesPanel.paginationLabel;\n noIssuesMessage ??= locale.IssuesPanel.noIssuesMessage;\n resolvedTitle ??= locale.IssuesPanel.resolvedTitle;\n resolvedMessage ??= locale.IssuesPanel.resolvedMessage;\n\n const [open, setOpen] = useControllableState(defaultOpen, controlledOpen);\n const formIsLoading = useFormIsLoading();\n const issuesTrackerResult = useIssuesTracker(AbsolutePath.MATCH_ALL, {\n enabled: open && !formIsLoading && !printing,\n issuesOrderCompareFn,\n });\n useReportValidationFailures(issuesTrackerResult.info);\n const latestInteraction = useLatestInteraction();\n const deferredIssuesTrackerResult = useDeferredValue(issuesTrackerResult);\n const { info } = deferredIssuesTrackerResult;\n const nPages = info?.length ?? 0;\n\n const [currentPagePath, setCurrentPagePath] = useIssuesPanelPath();\n const currentPageController = useController(\n currentPagePath ?? AbsolutePath.ROOT,\n { enabled: open && !formIsLoading && currentPagePath !== null },\n );\n\n // Obtain the index of the current page from the page path, and keep track\n // of the last existing page that we've visited\n const lastExistingPageIndex = useRef<number | null>(null);\n const currentPageIndex = useMemo(() => {\n const idx = currentPagePath\n ? (info?.findIndex(({ path }) => currentPagePath.equals(path)) ?? -1)\n : -1;\n if (idx !== -1) {\n lastExistingPageIndex.current = idx;\n }\n return idx;\n }, [currentPagePath, info]);\n\n // Go to a specified page and focus its respective field\n const focus = useFocus();\n const goToPath = useCallback(\n (path: AbsolutePath | null) => {\n setCurrentPagePath(path);\n if (path) {\n focus(path);\n }\n },\n [focus, setCurrentPagePath],\n );\n const goToPage = useCallback(\n (page: number) => {\n if (nPages > 0) {\n const clampedPage = Math.max(0, Math.min(page, nPages - 1));\n const newCurrentPath = info![clampedPage].path ?? null;\n goToPath(newCurrentPath);\n }\n },\n [goToPath, info, nPages],\n );\n const goToPreviousPage = useCallback(() => {\n if (currentPageIndex !== -1) {\n goToPage(currentPageIndex - 1);\n } else {\n goToPage((lastExistingPageIndex.current ?? 1) - 1);\n }\n }, [currentPageIndex, goToPage]);\n const goToNextPage = useCallback(() => {\n if (currentPageIndex !== -1) {\n goToPage(currentPageIndex + 1);\n } else {\n goToPage(lastExistingPageIndex.current ?? 0);\n }\n }, [currentPageIndex, goToPage]);\n const goToFirstPage = useCallback(() => goToPage(0), [goToPage]);\n const goToLastPage = useCallback(\n () => goToPage(nPages - 1),\n [goToPage, nPages],\n );\n\n const formManager = useFormManager();\n const formSchema = useMemo(() => formManager.schema(), [formManager]);\n // Keep track of latest `issuesOrderCompareFn` to use when getting the most\n // relevant issue path\n const issuesOrderCompareFnRef = useRef(issuesOrderCompareFn);\n issuesOrderCompareFnRef.current = issuesOrderCompareFn;\n\n // Focus initial issue when starting\n const [starting, setStarting] = useState(false);\n useEffect(() => {\n if (issuesTrackerResult.initialized && starting) {\n if (issuesTrackerResult.info.length > 0) {\n goToPath(\n mostRelevantIssuePath(\n issuesTrackerResult.info,\n latestInteraction,\n formSchema,\n issuesOrderCompareFnRef.current,\n ),\n );\n }\n setStarting(false);\n }\n }, [\n formSchema,\n goToPath,\n issuesTrackerResult.info,\n issuesTrackerResult.initialized,\n latestInteraction,\n starting,\n ]);\n\n // Starts the issues navigation\n const listeners = useLatestValues({ onOpenChange });\n const start = useCallback(() => {\n if (!open) {\n setOpen(true);\n listeners.onOpenChange?.(true);\n }\n setCurrentPagePath(null);\n setStarting(true);\n lastExistingPageIndex.current = null;\n }, [listeners, open, setCurrentPagePath, setOpen]);\n\n // Expose the `start` function to the form app\n useSetStartIssuesNavigation(start);\n\n // Keep track of the container's height\n const [containerEl, setContainerEl] = useState<HTMLDivElement | null>(null);\n const setBottomPanelHeight = useSetBottomPanelHeight();\n useMeasure(\n containerEl,\n useCallback(\n (measurement) => setBottomPanelHeight(measurement?.height),\n [setBottomPanelHeight],\n ),\n );\n\n // Sticky style for panel\n const formAppEl = useFormAppElement();\n useIntersectionObserver(\n containerEl,\n useCallback(\n (e) => setBoolDataAttr(containerEl, \"stuck\", e.intersectionRatio === 1),\n [containerEl],\n ),\n useMemo(\n () => ({\n root: formAppEl,\n rootMargin: `0px 0px -1px 0px`,\n threshold: [1],\n }),\n [formAppEl],\n ),\n );\n\n // Hides the issues panel\n const close = useCallback(() => {\n if (open) {\n setOpen(false);\n listeners.onOpenChange?.(false);\n }\n }, [listeners, open, setOpen]);\n\n const renderControls = (buttonsColor?: IconButtonColor) => (\n <IssuesPanelControls\n nPages={nPages}\n currentPagePath={currentPagePath}\n currentPageIndex={currentPageIndex}\n currentPageController={currentPageController}\n goToPreviousPage={goToPreviousPage}\n goToNextPage={goToNextPage}\n goToFirstPage={goToFirstPage}\n goToLastPage={goToLastPage}\n buttonsColor={buttonsColor}\n closePanel={close}\n focusButtonLabel={focusButtonLabel}\n previousIssueButtonLabel={previousIssueButtonLabel}\n nextIssueButtonLabel={nextIssueButtonLabel}\n firstIssueButtonLabel={firstIssueButtonLabel}\n lastIssueButtonLabel={lastIssueButtonLabel}\n paginationLabel={paginationLabel}\n validatingSpinnerProps={validatingSpinnerProps}\n paginationProps={paginationProps}\n focusButtonProps={focusButtonProps}\n previousIssueButtonProps={previousIssueButtonProps}\n nextIssueButtonProps={nextIssueButtonProps}\n firstIssueButtonProps={firstIssueButtonProps}\n lastIssueButtonProps={lastIssueButtonProps}\n closeButtonProps={closeButtonProps}\n />\n );\n\n const displayMode = useIssuesDisplayMode();\n const combinedContainerRef = useCombinedRef(\n setContainerEl,\n containerProps?.ref,\n );\n return (\n open &&\n !printing && (\n <div\n {...containerProps}\n className={cx(\n prefix(\"issues-panel__container\"),\n containerProps?.className,\n )}\n ref={combinedContainerRef}\n >\n <Container asChild fluid=\"md\">\n {displayMode === \"inline\" ? (\n <IssuesPanelSummaryCard\n issuesTrackerResult={deferredIssuesTrackerResult}\n renderControls={renderControls}\n errorsLabel={errorsLabel}\n warningsLabel={warningsLabel}\n noIssuesMessage={noIssuesMessage}\n headerProps={headerProps}\n loadingSpinnerProps={loadingSpinnerProps}\n titleProps={titleProps}\n iconProps={iconProps}\n {...otherProps}\n ref={forwardedRef}\n />\n ) : (\n <IssuesPanelMessagesCard\n currentPagePath={currentPagePath}\n currentPageController={currentPageController}\n issuesTrackerResult={deferredIssuesTrackerResult}\n currentPageIndex={currentPageIndex}\n displayIssueCodes={displayIssueCodes}\n unknownErrorMessage={unknownErrorMessage}\n unknownWarningMessage={unknownWarningMessage}\n renderControls={renderControls}\n errorsLabel={errorsLabel}\n warningsLabel={warningsLabel}\n noIssuesMessage={noIssuesMessage}\n resolvedTitle={resolvedTitle}\n resolvedMessage={resolvedMessage}\n headerProps={headerProps}\n bodyProps={bodyProps}\n loadingSpinnerProps={loadingSpinnerProps}\n titleProps={titleProps}\n iconProps={iconProps}\n {...otherProps}\n ref={forwardedRef}\n />\n )}\n </Container>\n </div>\n )\n );\n});\n\n/**\n * Function attempting to return the \"most relevant\" issue, given the list of\n * issue information, the path of the current page, and the path the user last\n * interacted with.\n */\nfunction mostRelevantIssuePath(\n info: LocatedValidationInfo[],\n latestInteraction: AbsolutePath,\n formSchema: Schema,\n issuesOrderCompareFn: IssuesTrackerOptions[\"issuesOrderCompareFn\"],\n): AbsolutePath {\n // Try to match the latest interaction exactly when a custom\n // `issuesOrderCompareFn` is provided, since we have no guarantee that the\n // first issue >= latest interaction will be the latest interaction itself\n // when it has an issue\n if (issuesOrderCompareFn) {\n for (const infoIssues of info) {\n if (latestInteraction.equals(infoIssues.path)) {\n return latestInteraction;\n }\n }\n }\n\n // Find index of first issues path >= latest interaction; if no such path\n // exists, set this index to the size of the info\n let indexOfInfoPathGteActivePath = info.findIndex(\n (issuesInfo) =>\n (issuesOrderCompareFn?.(issuesInfo.path, latestInteraction) ||\n compareSchemaPaths(formSchema, issuesInfo.path, latestInteraction)) >=\n 0,\n );\n if (indexOfInfoPathGteActivePath === -1) {\n indexOfInfoPathGteActivePath = info.length;\n }\n\n // Match a descendant of the latest interaction, or a descendant of one of its\n // ancestors\n let curPath = latestInteraction;\n while (!curPath.isRoot) {\n const curPathWithDescendants = curPath.append(\n AbsolutePathFragment.RecursiveWildcard,\n );\n for (let i = indexOfInfoPathGteActivePath; i < info.length; ++i) {\n if (curPathWithDescendants.matches(info[i].path)) {\n return info[i].path;\n }\n }\n for (let i = indexOfInfoPathGteActivePath - 1; i >= 0; --i) {\n if (curPathWithDescendants.matches(info[i].path)) {\n return info[i].path;\n }\n }\n curPath = curPath.parent();\n }\n return info[0].path;\n}\n","import { faFolderOpen } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n type ButtonProps,\n combineEventHandlers,\n useKeyboardShortcut,\n} from \"@ostack.tech/ui\";\nimport type { ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport {\n type FormLoaderOptions,\n useFormIsLoading,\n useFormLoader,\n} from \"../../utils/useFormLoader.tsx\";\nimport { useFormAppElement, useFormIsDisabled } from \"../FormApp\";\n\n/** Properties of the load action. */\nexport interface LoadActionProps<T = unknown>\n extends Omit<ButtonProps, \"children\">, FormLoaderOptions<T> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n}\n\n/** Action used to load a form from a file. */\nexport function LoadAction<T = unknown>({\n label,\n keybinds,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n ...otherProps\n}: LoadActionProps<T>) {\n const [locale] = useLocale();\n label ??= locale.LoadAction.label;\n keybinds ??= locale.LoadAction.keybinds;\n\n const { load } = useFormLoader({\n decode,\n path,\n extensions,\n mimeTypes,\n description,\n startIn,\n id,\n setPristineOnLoad,\n validateOnLoad,\n successMessage,\n errorMessage,\n });\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading;\n\n // Set-up keyboard shortcut\n const formAppEl = useFormAppElement();\n useKeyboardShortcut(keybinds, () => load(), {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <Button\n vertical\n variant=\"subtle\"\n icon={faFolderOpen}\n {...otherProps}\n onClick={combineEventHandlers(() => load(), onClick as never)}\n disabled={shouldDisable}\n loading={loading || formIsLoading}\n enabledWhenLoading={enabledWhenLoading}\n >\n {label}\n </Button>\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n formatNumericAsString,\n type Numeric,\n type NumericInputController,\n type NumericInputOptions,\n useNumericInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n NumericInput,\n type NumericValueRepresentations,\n useCombinedRef,\n warnOnce,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Kotlin integer types. */\nconst INTEGER_TYPES = [\"Byte\", \"Char\", \"Short\", \"Int\", \"Long\", \"BigInteger\"];\n\n/** Properties of the numeric control component. */\nexport interface NumericControlProps<T extends Numeric | null = Numeric | null>\n extends\n Omit<\n NumericInputOptions<T, string, ComponentRef<typeof NumericInput>>,\n \"enabled\" | \"formatFromString\" | \"parseToString\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof NumericInput>,\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"valueIsUnformattedString\"\n | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | NumericInputController<T, string, ComponentRef<typeof NumericInput>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Numeric control component supporting (possibly nullable) numeric schemas. */\nexport const NumericControl = forwardRef(function NumericControl<\n T extends Numeric | null = Numeric | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n valueIsInteger,\n scale,\n required,\n min,\n max,\n exclusiveMin,\n exclusiveMax,\n loading,\n disabled,\n readOnly,\n endAdornment,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: NumericControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof NumericInput>>,\n) {\n const [stringValue, setStringValue] = useState(\"\");\n const controller = useNumericInput<\n T,\n string,\n ComponentRef<typeof NumericInput>\n >(path, {\n enabled: !useFormIsLoading(),\n setFormattedValue: setStringValue,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLInputElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const latestStringValueRef = useRef(stringValue);\n latestStringValueRef.current = stringValue;\n const handleValueChange = useCallback(\n ({ stringValue }: NumericValueRepresentations) => {\n if (stringValue !== latestStringValueRef.current) {\n inputProps.onChange(stringValue);\n setStringValue(stringValue);\n }\n },\n [inputProps],\n );\n\n const schemaIsInteger = INTEGER_TYPES.includes(schema.typeInfo.name);\n if (schemaIsInteger && valueIsInteger !== undefined) {\n warnOnce(\n `NumericControl: At '${absolutePath.toString()}': Property ` +\n \"`valueIsInteger` has no effect (it will always be `true`) when the \" +\n \"control's schema is one of the integer types.\",\n );\n }\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedNumericInputRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <NumericInput\n value={stringValue}\n valueIsUnformattedString\n valueIsInteger={schemaIsInteger || valueIsInteger}\n scale={\n schemaIsInteger\n ? (scale ?? 0)\n : (scale ??\n (restrictions.scale == null\n ? undefined\n : (restrictions.scale as number)))\n }\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n min={\n min ??\n (restrictions.min == null\n ? undefined\n : formatNumericAsString(restrictions.min as T, schema))\n }\n max={\n max ??\n (restrictions.max == null\n ? undefined\n : formatNumericAsString(restrictions.max as T, schema))\n }\n exclusiveMin={\n exclusiveMin ??\n (restrictions.exclusiveMin == null\n ? undefined\n : formatNumericAsString(restrictions.exclusiveMin as T, schema))\n }\n exclusiveMax={\n exclusiveMax ??\n (restrictions.exclusiveMax == null\n ? undefined\n : formatNumericAsString(restrictions.exclusiveMax as T, schema))\n }\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={handleValueChange}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedNumericInputRef}\n />\n {inlineIssues}\n </>\n );\n});\n","import type { AbsolutePath, Path } from \"@ostack.tech/kform\";\nimport { useResolvedPath } from \"@ostack.tech/kform-react\";\nimport { combineEventHandlers, Link } from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithoutRef, MouseEvent } from \"react\";\n\nimport { useFocus } from \"../FormApp\";\n\n/** Default function used to build a link's `href` from a path. */\nconst DEFAULT_HREF_BUILDER = (path: AbsolutePath) => path.toString();\n\n/** Properties of the path link component. */\nexport interface PathLinkProps extends Omit<\n ComponentPropsWithoutRef<typeof Link>,\n \"href\"\n> {\n /** KForm path to link to. */\n to: string | Path;\n /**\n * Function used to build the link's `href` from the path.\n *\n * @default (path) => path.toString()\n */\n buildHref?: (path: AbsolutePath) => string;\n}\n\n/** Link to a KForm path. */\nexport function PathLink({\n to,\n buildHref = DEFAULT_HREF_BUILDER,\n onClick,\n ...otherProps\n}: PathLinkProps) {\n const focus = useFocus();\n const path = useResolvedPath(to);\n\n const handleClick = (evt: MouseEvent) => {\n evt.preventDefault();\n focus(path);\n };\n\n return (\n <Link\n href={buildHref(path)}\n {...otherProps}\n onClick={combineEventHandlers(onClick, handleClick, {\n checkDefaultPrevented: true,\n })}\n />\n );\n}\n","import { faPrint } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n type ButtonProps,\n combineEventHandlers,\n PrinterTrigger,\n useKeyboardShortcut,\n usePrint,\n usePrinterDocumentTitle,\n usePrintInProgress,\n} from \"@ostack.tech/ui\";\nimport { format } from \"date-fns\";\nimport type { MouseEvent, ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useFormAppElement, useFormIsDisabled, useFormTitle } from \"../FormApp\";\n\n/** Properties of the print action. */\nexport interface PrintActionProps extends Omit<ButtonProps, \"children\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n}\n\n/**\n * Action used to print the form application. Requires the `<FormApp>` component\n * to be wrapped in a `<Printer>` component, and for the `<PrinterContent>` to\n * wrap all annexes/pages/form controls.\n *\n * This typically looks something like:\n *\n * ```tsx\n * <Printer>\n * <FormApp>\n * <PrinterContent>\n * <TopBar>\n * …\n * <PrintAction />…\n * </TopBar>\n * …\n * </PrinterContent>\n * </FormApp>\n * </Printer>;\n * ```\n */\nexport function PrintAction({\n label,\n keybinds,\n disabled,\n loading,\n enabledWhenLoading,\n onClick,\n ...otherProps\n}: PrintActionProps) {\n const [locale] = useLocale();\n label ??= locale.PrintAction.label;\n keybinds ??= locale.PrintAction.keybinds;\n\n const printInProgress = usePrintInProgress();\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading ||\n printInProgress;\n\n // Set-up keyboard shortcut\n const formAppEl = useFormAppElement();\n const formTitle = useFormTitle();\n const print = usePrint();\n\n // Only provide a default `documentTitle` if the one is not provided in the\n // `Printer` component\n const printerHasDocumentTitle = !!usePrinterDocumentTitle();\n const handlePrint = (evt: MouseEvent | KeyboardEvent) => {\n evt.preventDefault();\n void print(\n printerHasDocumentTitle\n ? undefined\n : { documentTitle: defaultDocumentTitle(formTitle) },\n );\n };\n\n useKeyboardShortcut(keybinds, handlePrint, {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <PrinterTrigger\n onClick={combineEventHandlers(onClick, handlePrint, {\n checkDefaultPrevented: true,\n })}\n >\n <Button\n vertical\n variant=\"subtle\"\n icon={faPrint}\n {...otherProps}\n loading={loading || printInProgress}\n disabled={shouldDisable}\n >\n {label}\n </Button>\n </PrinterTrigger>\n );\n}\n\n/** Default document title when one is not provided. */\nfunction defaultDocumentTitle(formTitle?: string) {\n const date = format(new Date(), \"yyyy-MM-dd\");\n return [formTitle, date].filter(Boolean).join(\" \");\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n equals,\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n Radio,\n RadioGroup,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type Key,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport {\n formatSelectionValueAsOptionIndex,\n parseSelectionValueFromOptionIndex,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Radio in object notation. */\nexport type RadioObject<T = unknown> = Omit<\n ComponentPropsWithRef<typeof Radio>,\n \"value\" | \"children\"\n> & {\n /** Option value. */\n value: T;\n /** Option's rendered text. */\n text?: ReactNode;\n /** Option's unique key. */\n key?: Key;\n};\n\n/** Properties of the radio group control component. */\nexport interface RadioGroupControlProps<T = unknown>\n extends\n Omit<\n InputOptions<T, string, ComponentRef<typeof RadioGroup>>,\n \"enabled\" | \"format\" | \"parse\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof RadioGroup>,\n \"defaultValue\" | \"value\" | \"onValueChange\" | \"children\" | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /** RadioGroup control options. */\n options: RadioObject<T>[];\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n InputController<T, string, ComponentRef<typeof RadioGroup>> | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Radio group control component supporting schemas of any type. */\nexport const RadioGroupControl = forwardRef(function RadioGroupControl<\n T = unknown,\n>(\n {\n path,\n options,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n showClearButton = false,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: RadioGroupControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof RadioGroup>>,\n) {\n const [value, setValue] = useState<T>();\n const formattedValue = useMemo(\n () => formatSelectionValueAsOptionIndex(value, options),\n [options, value],\n );\n const controller = useInput<T, string, ComponentRef<typeof RadioGroup>>(\n path,\n {\n enabled: !useFormIsLoading(),\n parse: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n format: useCallback(\n (value: T | undefined) =>\n formatSelectionValueAsOptionIndex(value, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n setValue(\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n },\n );\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { nullable, restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLDivElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string) =>\n setValue(\n parseSelectionValueFromOptionIndex(formattedValue, schema, options),\n ),\n [options, schema],\n );\n\n // Get representation of the value that the control will be cleared to. When\n // `showClearButton` is \"auto\", we hide the button if the current value is\n // the same as the \"cleared value\".\n const clearedValue = nullable ? null : schema.initialValue;\n const clearedIdx = useMemo(\n () => options.findIndex((option) => equals(option.value, clearedValue)),\n [clearedValue, options],\n );\n const clearedFormattedValue = clearedIdx === -1 ? \"\" : clearedIdx.toString();\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedRadioGroupRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <RadioGroup\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n showClearButton={\n showClearButton === \"auto\"\n ? formattedValue !== clearedFormattedValue\n : showClearButton\n }\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedRadioGroupRef}\n >\n {options.map(({ value, text, key, ...radioProps }, i) => (\n <Radio key={key ?? i} value={i} {...radioProps}>\n {text ?? value?.toString() ?? \"\"}\n </Radio>\n ))}\n </RadioGroup>\n {inlineIssues}\n {popoverIssues}\n </>\n );\n});\n","import { AbsolutePath } from \"@ostack.tech/kform\";\nimport { useFormController, useFormManager } from \"@ostack.tech/kform-react\";\nimport { useToastManager } from \"@ostack.tech/ui\";\nimport {\n fileSave,\n type FileSystemHandle,\n supported,\n type WellKnownDirectory,\n} from \"browser-fs-access\";\nimport { format } from \"date-fns\";\nimport { type ReactNode, useMemo } from \"react\";\n\nimport { useFormTitle } from \"../components/FormApp\";\nimport { useLocale } from \"../providers/LocalizationProvider\";\n\n/**\n * Options that can be passed to the {@link useFormSaver} hook, or to its\n * resulting `save`/`saveAs` functions.\n */\nexport interface FormSaverOptions<T = unknown> {\n /**\n * When set, if modern file system APIs are available and the form has been\n * previously loaded or saved, then the file will be written over the\n * previously saved/loaded file.\n *\n * @default false\n */\n overwrite?: boolean;\n /**\n * Function used to encode the form, given its value.\n *\n * Note that when returning a string, the string is converted into a `Blob`\n * using the first provided mime type in `mimeTypes` as its type, _i.e._ it is\n * converted as `new Blob([encodedValue], { type: mimeTypes?.[0] })`.\n *\n * @param formValue Value of the form.\n * @returns Encoded form value as a string, blob, response, or a promise to\n * either type.\n */\n encode?: (\n formValue: T,\n ) => string | Blob | Response | PromiseLike<string | Blob | Response>;\n /**\n * Path of the value being saved.\n *\n * @default AbsolutePath.ROOT\n */\n path?: string | AbsolutePath;\n /**\n * Suggested file name.\n *\n * A function may be provided which will be called with the form value right\n * before invoking the save.\n */\n fileName?: string | ((formValue: T) => string | PromiseLike<string>);\n /**\n * Acceptable file extensions. Extensions should include the leading dot.\n *\n * _E.g._ `[\".json\", \".txt\"]`\n *\n * @default [\"\"]\n */\n extensions?: string[];\n /**\n * Acceptable MIME types.\n *\n * _E.g._ `[\"application/json\", \"text/plain\"]`\n *\n * @default [ ]\n */\n mimeTypes?: string[];\n /**\n * Suggested file description.\n *\n * @default \"\"\n */\n description?: string;\n /** Directory to present when starting to save. */\n startIn?: WellKnownDirectory | FileSystemHandle;\n /** Excludes the \"accept all\" option. */\n excludeAcceptAllOption?: boolean;\n /**\n * By specifying an ID, the user agent can remember different directories for\n * different IDs.\n */\n id?: string;\n /**\n * Whether to set the form as pristine when saving.\n *\n * @default true\n */\n setPristineOnSave?: boolean;\n /**\n * Message to show in a toast when successfully saving the form to a file. Can\n * be set to `null` to not show any message.\n *\n * @param fileHandle Handle to the saved file.\n * @returns Message to show in a toast.\n */\n successMessage?:\n | ReactNode\n | ((fileHandle: FileSystemFileHandle) => ReactNode);\n /**\n * Message to show in a toast when an error occurs while saving the form to a\n * file. Can be set to `null` to not show any message.\n *\n * @param fileHandle Handle of the file over which the save was attempted, or\n * `null` if no such file exists.\n * @param error Error that occurred.\n * @returns Message to show in a toast.\n */\n errorMessage?:\n | ReactNode\n | ((fileHandle: FileSystemFileHandle | null, error: unknown) => ReactNode);\n}\n\n/** Result of the {@link useFormSaver} hook. */\nexport interface FormSaverResult<T> {\n /**\n * Function used to save the form.\n *\n * @param options Options used for saving the form.\n * @returns Promise which resolves once the form has been saved.\n */\n save: (options?: FormSaverOptions<T>) => Promise<void>;\n /** Whether the browser supports modern file system APIs used for saving. */\n supportsFileSystemAPIs: boolean;\n}\n\n/** Hook exposing functions used to save the form to a file. */\nexport function useFormSaver<T = unknown>({\n overwrite,\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n setPristineOnSave,\n successMessage,\n errorMessage,\n}: FormSaverOptions<T> = {}): FormSaverResult<T> {\n const [locale] = useLocale();\n const formManager = useFormManager();\n const { getState, _setState } = useFormController();\n const { addToast } = useToastManager();\n const formTitle = useFormTitle();\n\n return useMemo(() => {\n async function save<T = unknown>({\n overwrite,\n path = AbsolutePath.ROOT,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id = \"\",\n setPristineOnSave = true,\n successMessage,\n errorMessage,\n }: FormSaverOptions<T>) {\n if (!encode) {\n throw new Error(\"No `encode` function was provided.\");\n }\n if (successMessage === undefined) {\n successMessage = locale.SaveAction.successMessage;\n }\n if (errorMessage === undefined) {\n errorMessage = locale.SaveAction.errorMessage;\n }\n\n _setState({ saving: true } as any);\n let fileHandle: FileSystemFileHandle | null =\n (getState() as any).latestFileHandles?.[id] ?? null;\n try {\n const [encodedForm, suggestedFileName] = await formManager.get<\n T,\n [string | Blob | Response, string | undefined]\n >(path, (value) =>\n Promise.all([\n encode(value),\n fileHandle\n ? fileHandle.name\n : typeof fileName === \"function\"\n ? fileName(value)\n : fileName,\n ]),\n );\n\n fileHandle = await fileSave(\n typeof encodedForm === \"string\"\n ? new Blob([encodedForm], { type: mimeTypes?.[0] })\n : encodedForm,\n {\n fileName:\n suggestedFileName || defaultFileName(formTitle, extensions?.[0]),\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n },\n overwrite ? fileHandle : null,\n );\n\n if (setPristineOnSave) {\n await formManager.setPristine(path);\n }\n\n _setState(\n (state: any) =>\n ({\n latestFileHandles: {\n ...state.latestFileHandles,\n [id]: fileHandle,\n },\n }) as any,\n );\n\n // When modern file system APIs aren't available, the browser will show\n // a notification for the downloaded file so the toast is unnecessary\n if (supported) {\n const message =\n typeof successMessage == \"function\"\n ? successMessage(fileHandle!)\n : successMessage;\n if (message != null) {\n addToast(message, { severity: \"success\" });\n }\n }\n } catch (err) {\n // User aborted\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(err);\n }\n const message =\n typeof errorMessage == \"function\"\n ? errorMessage(fileHandle, err)\n : errorMessage;\n if (message != null) {\n addToast(message, { severity: \"danger\" });\n }\n } finally {\n _setState({ saving: false } as any);\n }\n }\n\n return {\n save: (options = {}) =>\n save({\n overwrite,\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n setPristineOnSave,\n successMessage,\n errorMessage,\n ...options,\n }),\n supportsFileSystemAPIs: supported,\n };\n }, [\n _setState,\n addToast,\n description,\n encode,\n errorMessage,\n excludeAcceptAllOption,\n extensions,\n fileName,\n formManager,\n formTitle,\n getState,\n id,\n locale.SaveAction.errorMessage,\n locale.SaveAction.successMessage,\n mimeTypes,\n overwrite,\n path,\n setPristineOnSave,\n startIn,\n successMessage,\n ]);\n}\n\n/** Hook exposing whether the form is currently being saved. */\nexport function useFormIsSaving() {\n return useFormController().useState((state) => (state as any).saving);\n}\n\n/** Default file name when one is not provided. */\nfunction defaultFileName(formTitle?: string, extension?: string) {\n const date = format(new Date(), \"yyyy-MM-dd\");\n return [[formTitle, date].filter(Boolean).join(\" \"), extension]\n .filter(Boolean)\n .join(\"\");\n}\n","import { faCaretDown, faFloppyDisk } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n ButtonGroup,\n type ButtonProps,\n combineEventHandlers,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n IconButton,\n useKeyboardShortcut,\n} from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport {\n type FormSaverOptions,\n useFormIsSaving,\n useFormSaver,\n} from \"../../utils/useFormSaver.tsx\";\nimport { useFormAppElement } from \"../FormApp\";\n\n/** Properties of the save action. */\nexport interface SaveActionProps<T = unknown>\n extends\n Omit<ButtonProps, \"children\">,\n Omit<FormSaverOptions<T>, \"overwrite\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n /**\n * Whether to disable the overwriting behaviour of the “save” button. When\n * set, the “save” button will function as the “save as” button and the “save\n * as” button will not be rendered.\n *\n * This property only affects browsers that support modern file system APIs,\n * since other browsers already function in the above-mentioned way.\n */\n disableOverwrite?: boolean;\n /** Label of the save options button. */\n saveOptionsLabel?: ReactNode;\n /** Label of the action's \"save as\" sub-action. */\n saveAsLabel?: ReactNode;\n /**\n * Keybinds for triggering the \"save as\" sub-action. Set to `null` to disable\n * the keyboard shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n saveAsKeybinds?: string | string[] | null;\n /** Properties to pass to the save options button component. */\n saveOptionsProps?: Omit<\n Partial<ComponentPropsWithRef<typeof IconButton>>,\n \"label\"\n >;\n /** Properties to pass to the save options dropdown menu component. */\n dropdownMenuProps?: ComponentPropsWithRef<typeof DropdownMenuContent>;\n}\n\n/** Action used to save the form to a file. */\nexport function SaveAction<T = unknown>({\n label,\n keybinds,\n disableOverwrite,\n saveOptionsLabel,\n saveAsLabel,\n saveAsKeybinds,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n variant = \"subtle\",\n color,\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n successMessage,\n errorMessage,\n saveOptionsProps,\n dropdownMenuProps,\n ...otherProps\n}: SaveActionProps<T>) {\n const [locale] = useLocale();\n label ??= locale.SaveAction.label;\n keybinds ??= locale.SaveAction.keybinds;\n saveOptionsLabel ??= locale.SaveAction.saveOptionsLabel;\n saveAsLabel ??= locale.SaveAction.saveAsLabel;\n saveAsKeybinds ??= locale.SaveAction.saveAsKeybinds;\n\n const { save, supportsFileSystemAPIs } = useFormSaver({\n path,\n encode,\n fileName,\n extensions,\n description,\n mimeTypes,\n startIn,\n excludeAcceptAllOption,\n id,\n successMessage,\n errorMessage,\n });\n const formIsSaving = useFormIsSaving();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsSaving ||\n formIsLoading;\n\n // Set-up keyboard shortcuts\n const formAppEl = useFormAppElement();\n useKeyboardShortcut(keybinds, () => save({ overwrite: !disableOverwrite }), {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n useKeyboardShortcut(saveAsKeybinds, () => save(), {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n const saveButton = (\n <Button\n vertical\n variant={variant}\n color={color}\n icon={faFloppyDisk}\n {...otherProps}\n onClick={combineEventHandlers(\n () => save({ overwrite: !disableOverwrite }),\n onClick as never,\n )}\n disabled={shouldDisable}\n loading={loading || formIsSaving}\n enabledWhenLoading={enabledWhenLoading}\n >\n {label}\n </Button>\n );\n\n return supportsFileSystemAPIs && !disableOverwrite ? (\n <ButtonGroup>\n {saveButton}\n <DropdownMenu>\n <DropdownMenuTrigger>\n <IconButton\n variant={variant}\n color={color}\n icon={faCaretDown}\n {...saveOptionsProps}\n label={saveOptionsLabel}\n disabled={shouldDisable || saveOptionsProps?.disabled}\n style={{ minWidth: 20, ...saveOptionsProps?.style }}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" {...dropdownMenuProps}>\n <DropdownMenuItem onClick={() => save()} disabled={shouldDisable}>\n {saveAsLabel}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </ButtonGroup>\n ) : (\n saveButton\n );\n}\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n equals,\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport { combineEventHandlers, Select, useCombinedRef } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport type { OptionObject, OptionsGroupObject } from \"../../utils/options.ts\";\nimport {\n formatSelectionValueAsOptionIndex,\n optionObjectsToNodes,\n parseSelectionValueFromOptionIndex,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the select control component. */\nexport interface SelectControlProps<T = unknown>\n extends\n Omit<\n InputOptions<T, string, ComponentRef<typeof Select>>,\n \"enabled\" | \"format\" | \"parse\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Select>,\n | \"multiple\"\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"children\"\n | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /** Select control options. */\n options: (OptionsGroupObject<T> | OptionObject<T>)[];\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n InputController<T, string, ComponentRef<typeof Select>> | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Select control component supporting schemas of any type. */\nexport const SelectControl = forwardRef(function SelectControl<T = unknown>(\n {\n path,\n options: groupedOptions,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n showClearButton,\n endAdornment,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: SelectControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Select>>,\n) {\n const options = useMemo(\n () =>\n groupedOptions.reduce((options: OptionObject<T>[], optionOrGroup) => {\n if (\"options\" in optionOrGroup) {\n options.push(...optionOrGroup.options);\n } else {\n options.push(optionOrGroup);\n }\n return options;\n }, []),\n [groupedOptions],\n );\n const [value, setValue] = useState<T>();\n const formattedValue = useMemo(\n () => formatSelectionValueAsOptionIndex(value, options),\n [options, value],\n );\n const controller = useInput<T, string, ComponentRef<typeof Select>>(path, {\n enabled: !useFormIsLoading(),\n parse: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n format: useCallback(\n (value: T | undefined) =>\n formatSelectionValueAsOptionIndex(value, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (formattedValue: string, state: FormatterControllerState<T, string>) =>\n setValue(\n parseSelectionValueFromOptionIndex(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { getState, useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { nullable, restrictions } = schema.typeInfo;\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<T, HTMLButtonElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string) =>\n setValue(\n parseSelectionValueFromOptionIndex(\n formattedValue,\n getState().schema,\n options,\n ),\n ),\n [getState, options],\n );\n\n // Get representation of the value that the control will be cleared to. When\n // `showClearButton` is \"auto\", we hide the button if the current value is\n // the same as the \"cleared value\".\n showClearButton ??= nullable ? \"auto\" : false;\n const clearedValue = nullable ? null : schema.initialValue;\n const clearedIdx = useMemo(\n () => options.findIndex((option) => equals(option.value, clearedValue)),\n [clearedValue, options],\n );\n const clearedFormattedValue = clearedIdx === -1 ? \"\" : clearedIdx.toString();\n\n const optionNodes = useMemo(\n () => optionObjectsToNodes(groupedOptions),\n [groupedOptions],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedSelectRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Select\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n showClearButton={\n showClearButton === \"auto\"\n ? formattedValue !== clearedFormattedValue\n : showClearButton\n }\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedSelectRef}\n >\n {optionNodes}\n </Select>\n {inlineIssues}\n </>\n );\n});\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type Listable,\n type ListableInputController,\n type ListableInputOptions,\n useListableInput,\n} from \"@ostack.tech/kform-react\";\nimport { combineEventHandlers, Select, useCombinedRef } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport type { OptionObject, OptionsGroupObject } from \"../../utils/options.ts\";\nimport {\n formatSelectionValuesAsOptionIndices,\n optionObjectsToNodes,\n parseSelectionValuesFromOptionIndices,\n} from \"../../utils/selectionTransformations.tsx\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the select multiple control component. */\nexport interface SelectMultipleControlProps<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n>\n extends\n Omit<\n ListableInputOptions<T, TListable, string[], ComponentRef<typeof Select>>,\n \"enabled\" | \"formatFromArray\" | \"parseToArray\"\n >,\n Omit<\n ComponentPropsWithoutRef<typeof Select>,\n | \"multiple\"\n | \"defaultValue\"\n | \"value\"\n | \"onValueChange\"\n | \"children\"\n | \"status\"\n > {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /** Select multiple control options. */\n options: (OptionsGroupObject<T> | OptionObject<T>)[];\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | ListableInputController<\n T,\n TListable,\n string[],\n ComponentRef<typeof Select>\n >\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/**\n * Select multiple control component supporting (possibly nullable) listable\n * schemas with elements of any type.\n *\n * If the schema is nullable, this component sets the form value to `null` when\n * the control contains no elements. Note, however, that the form may still hold\n * an empty listable as value if set programmatically.\n */\nexport const SelectMultipleControl = forwardRef(function SelectMultipleControl<\n T = unknown,\n TListable extends Listable<T> | null = Listable<T> | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n options: groupedOptions,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n loading,\n disabled,\n readOnly,\n endAdornment,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: SelectMultipleControlProps<T, TListable>,\n forwardedRef: ForwardedRef<ComponentRef<typeof Select>>,\n) {\n const options = useMemo(\n () =>\n groupedOptions.reduce((options: OptionObject<T>[], optionOrGroup) => {\n if (\"options\" in optionOrGroup) {\n options.push(...optionOrGroup.options);\n } else {\n options.push(optionOrGroup);\n }\n return options;\n }, []),\n [groupedOptions],\n );\n const [arrayValue, setArrayValue] = useState<T[] | null>(null);\n const formattedValue = useMemo(\n () => formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options, arrayValue],\n );\n const controller = useListableInput<\n T,\n TListable,\n string[],\n ComponentRef<typeof Select>\n >(path, {\n enabled: !useFormIsLoading(),\n parseToArray: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n [options],\n ),\n formatFromArray: useCallback(\n (arrayValue: T[] | null) =>\n formatSelectionValuesAsOptionIndices(arrayValue, options),\n [options],\n ),\n setFormattedValue: useCallback(\n (\n formattedValue: string[],\n state: FormatterControllerState<TListable, string[]>,\n ) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n state.schema,\n options,\n ),\n ),\n [options],\n ),\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { getState, useSchema, usePath, inputProps } = controller;\n const { restrictions } = useSchema().typeInfo;\n const absolutePath = usePath();\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<TListable, HTMLButtonElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const handleValueChange = useCallback(\n (formattedValue: string[]) =>\n setArrayValue(\n parseSelectionValuesFromOptionIndices(\n formattedValue,\n getState().schema,\n options,\n ),\n ),\n [getState, options],\n );\n\n const optionNodes = useMemo(\n () => optionObjectsToNodes(groupedOptions),\n [groupedOptions],\n );\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const combinedSelectRef = useCombinedRef(\n inputProps.ref,\n autofocusRef,\n forwardedRef,\n );\n return (\n <>\n <Select\n multiple\n value={formattedValue}\n name={inputProps.name}\n required={required ?? restrictions.required === true}\n loading={displayLoading || loading}\n disabled={displayDisabled || disabled}\n readOnly={displayReadOnly || readOnly || inputProps.readOnly}\n status={displayStatusToControlStatus(displayStatusToDisplay)}\n endAdornment={\n <>\n {popoverIssues}\n {endAdornment}\n </>\n }\n onValueChange={combineEventHandlers(\n inputProps.onChange,\n handleValueChange,\n )}\n onFocus={combineEventHandlers(onFocus, handleFocus)}\n onBlurToOutside={combineEventHandlers(\n onBlurToOutside,\n inputProps.onBlur,\n )}\n {...otherProps}\n ref={combinedSelectRef}\n >\n {optionNodes}\n </Select>\n {inlineIssues}\n </>\n );\n});\n","import { faArrowRight } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n type FormManager,\n type LocatedValidationWarning,\n PromiseCancellationException,\n type SealedLocatedValidationIssue,\n} from \"@ostack.tech/kform\";\nimport {\n type SubmitOptions,\n useFormController,\n} from \"@ostack.tech/kform-react\";\nimport {\n Alert,\n AlertDialog,\n AlertDialogAction,\n AlertDialogBody,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n type ButtonProps,\n Checkbox,\n type CheckboxChecked,\n combineEventHandlers,\n cx,\n Stack,\n useKeyboardShortcut,\n useToastManager,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithRef,\n type MouseEvent,\n type ReactNode,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport {\n useFormAppElement,\n useFormIsDisabled,\n useStartIssuesNavigation,\n} from \"../FormApp\";\n\n/** Properties of the submit action. */\nexport interface SubmitActionProps<T = unknown, TSubmitResult = unknown>\n extends\n Omit<ButtonProps, \"children\" | \"onSubmit\">,\n Pick<Required<SubmitOptions<T, TSubmitResult>>, \"onSubmit\">,\n Omit<SubmitOptions<T, TSubmitResult>, \"onSubmit\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n /**\n * Whether users should confirm (by ticking a checkbox) that the submission\n * should proceed whenever the form contains warnings.\n *\n * @default true\n */\n confirmWarnings?: boolean;\n /** Title of the confirmation dialog which appears when submitting the form. */\n dialogTitle?:\n | ReactNode\n | ((formValue: T, warnings?: LocatedValidationWarning[]) => ReactNode);\n /**\n * Description of the confirmation dialog which appears when submitting the\n * form.\n */\n dialogDescription?:\n | ReactNode\n | ((formValue: T, warnings?: LocatedValidationWarning[]) => ReactNode);\n /**\n * Body of the confirmation dialog which appears when submitting the form.\n *\n * This property can be used to display a summary of the data being submitted\n * and will be displayed between the description and the “confirm warnings\n * alert”, when it exists.\n */\n dialogBody?:\n | ReactNode\n | ((formValue: T, warnings?: LocatedValidationWarning[]) => ReactNode);\n /**\n * Label of the checkbox which prompts users to confirm that they intend to\n * proceed with submission in the event of warnings in the form.\n */\n confirmWarningsCheckboxLabel?: ReactNode;\n /**\n * Text of the OK button in the confirmation dialog which appears when\n * submitting the form.\n */\n dialogOkText?: ReactNode;\n /**\n * Text of the cancel button in the confirmation dialog which appears when\n * submitting the form.\n */\n dialogCancelText?: ReactNode;\n /**\n * Message to show in a toast after a successful submission. Can be set to\n * `null` to not show any message.\n *\n * @param submitResult Result of `onSubmit`.\n * @returns Message to show in a toast.\n */\n successMessage?: ReactNode | ((submitResult: TSubmitResult) => ReactNode);\n /**\n * Message to show in a toast when an error occurs while submitting the form.\n * Can be set to `null` to not show any message.\n *\n * @param error Error that occurred.\n * @returns Message to show in a toast.\n */\n errorMessage?: ReactNode | ((error: unknown) => ReactNode);\n /** Properties to pass to the confirmation dialog content component. */\n dialogContentProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogContent>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog header component. */\n dialogHeaderProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogHeader>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog title component. */\n dialogTitleProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogTitle>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog body component. */\n dialogBodyProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogBody>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog description component. */\n dialogDescriptionProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogDescription>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog footer component. */\n dialogFooterProps?: Omit<\n ComponentPropsWithRef<typeof AlertDialogFooter>,\n \"children\"\n >;\n /** Properties to pass to the confirmation dialog OK button component. */\n dialogOkButtonProps?: Omit<ComponentPropsWithRef<typeof Button>, \"children\">;\n /** Properties to pass to the confirmation dialog cancel button component. */\n dialogCancelButtonProps?: Omit<\n ComponentPropsWithRef<typeof Button>,\n \"children\"\n >;\n /** Properties to pass to the alert used to confirm warnings. */\n confirmWarningsAlertProps?: Omit<\n ComponentPropsWithRef<typeof Alert>,\n \"children\"\n >;\n /** Properties to pass to the checkbox used to confirm warnings. */\n confirmWarningsCheckboxProps?: Omit<\n ComponentPropsWithRef<typeof Checkbox>,\n \"checked\" | \"onCheckedChange\" | \"children\"\n >;\n}\n\n/**\n * Type of external issues accepted by the form manager's `addExternalIssues`\n * method.\n */\ntype ExternalValidationIssues = Parameters<FormManager[\"addExternalIssues\"]>[0];\n\n/** An object which is event-like. */\ntype EventLike = Pick<Event, \"preventDefault\" | \"defaultPrevented\">;\n\n/** Information about a submission. */\ninterface SubmissionInfo<T = unknown, TSubmitResult = unknown> {\n value: T;\n warnings?: LocatedValidationWarning[];\n resolve: (value: ExternalValidationIssues | TSubmitResult) => void;\n reject: (reason?: any) => void;\n}\n\n/** Action used to submit the form. */\nexport function SubmitAction<T = unknown, TSubmitResult = unknown>({\n onSubmit,\n onInvalidSubmit,\n onSuccessfulSubmit,\n onFailedSubmit,\n setTouchedOnSubmit,\n validateOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n label,\n keybinds,\n confirmWarnings = true,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n dialogTitle,\n dialogDescription,\n dialogBody,\n confirmWarningsCheckboxLabel,\n dialogOkText,\n dialogCancelText,\n successMessage,\n errorMessage,\n dialogContentProps,\n dialogHeaderProps,\n dialogTitleProps,\n dialogBodyProps,\n dialogDescriptionProps,\n dialogFooterProps,\n dialogOkButtonProps,\n dialogCancelButtonProps,\n confirmWarningsAlertProps,\n confirmWarningsCheckboxProps,\n ...otherProps\n}: SubmitActionProps<T, TSubmitResult>) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n label ??= locale.SubmitAction.label;\n keybinds ??= locale.SubmitAction.keybinds;\n dialogTitle ??= locale.SubmitAction.dialogTitle;\n dialogDescription ??= locale.SubmitAction.dialogDescription;\n dialogBody ??= locale.SubmitAction.dialogBody;\n confirmWarningsCheckboxLabel ??=\n locale.SubmitAction.confirmWarningsCheckboxLabel;\n dialogOkText ??= locale.SubmitAction.dialogOkText ?? label;\n dialogCancelText ??= locale.SubmitAction.dialogCancelText;\n if (successMessage === undefined) {\n successMessage = locale.SubmitAction.successMessage;\n }\n if (errorMessage === undefined) {\n errorMessage = locale.SubmitAction.errorMessage;\n }\n\n const [confirmingSubmission, setConfirmingSubmission] = useState(false);\n const startIssuesNavigation = useStartIssuesNavigation();\n const { addToast } = useToastManager();\n const { submit, useSubmitting } = useFormController<T>();\n const submitting = useSubmitting();\n const [runningOnSubmit, setRunningOnSubmit] = useState(false);\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const formAppEl = useFormAppElement();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading ||\n submitting;\n\n const [submissionInfo, setSubmissionInfo] = useState<SubmissionInfo<\n T,\n TSubmitResult\n > | null>(null);\n const [checkedWarnings, setCheckedWarnings] = useState<\n LocatedValidationWarning[]\n >([]);\n const allWarningsChecked =\n !submissionInfo?.warnings ||\n submissionInfo.warnings.every((warning) =>\n checkedWarnings.some((checkedWarning) => warning.equals(checkedWarning)),\n );\n\n const handleSubmit = (\n value: T,\n warnings?: LocatedValidationWarning[],\n event?: EventLike,\n ) => {\n event?.preventDefault?.();\n return new Promise<ExternalValidationIssues | TSubmitResult>(\n (resolve, reject) => {\n setConfirmingSubmission(true);\n setSubmissionInfo({ value, warnings, resolve, reject });\n },\n );\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open && !runningOnSubmit) {\n submissionInfo?.reject(\n new PromiseCancellationException(\"Submission cancelled\"),\n );\n setSubmissionInfo(null);\n setConfirmingSubmission(false);\n }\n };\n\n const handleInvalidSubmit = async (\n issues: SealedLocatedValidationIssue[],\n event?: EventLike,\n ) => {\n await startIssuesNavigation({ validate: false });\n onInvalidSubmit?.(issues, event);\n };\n\n const handleSuccessfulSubmit = (\n submitResult: TSubmitResult,\n event?: EventLike,\n ) => {\n const message =\n typeof successMessage === \"function\"\n ? successMessage(submitResult)\n : successMessage;\n if (message != null) {\n addToast(message, { severity: \"success\" });\n }\n onSuccessfulSubmit?.(submitResult, event);\n };\n\n const handleFailedSubmit = (error: unknown, event?: EventLike) => {\n if (error instanceof PromiseCancellationException) {\n return;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(error);\n }\n const message =\n typeof errorMessage === \"function\" ? errorMessage(error) : errorMessage;\n if (message != null) {\n addToast(message, { severity: \"danger\" });\n }\n onFailedSubmit?.(error, event);\n };\n\n const handleConfirmSubmit = async (event: MouseEvent) => {\n event.preventDefault();\n if (!submissionInfo) {\n return;\n }\n\n const { value, warnings, resolve, reject } = submissionInfo;\n try {\n setRunningOnSubmit(true);\n resolve(await onSubmit(value, warnings, event));\n } catch (err) {\n reject(err);\n } finally {\n setRunningOnSubmit(false);\n handleOpenChange(false);\n }\n };\n\n const handleOnCheckedChange = (checked: CheckboxChecked) => {\n setCheckedWarnings(checked ? (submissionInfo?.warnings ?? []) : []);\n };\n\n const handleAction = (event: EventLike) =>\n submit(event, {\n onSubmit: handleSubmit,\n onInvalidSubmit: handleInvalidSubmit,\n onSuccessfulSubmit: handleSuccessfulSubmit,\n onFailedSubmit: handleFailedSubmit,\n setTouchedOnSubmit,\n validateOnSubmit,\n setPristineOnSuccessfulSubmit,\n convertExternalIssuesTableRowIndicesToIds,\n });\n\n // Set-up keyboard shortcut\n useKeyboardShortcut(keybinds, handleAction, {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <AlertDialog open={confirmingSubmission} onOpenChange={handleOpenChange}>\n <AlertDialogTrigger>\n <Button\n type=\"submit\"\n color=\"success\"\n icon={faArrowRight}\n iconPlacement=\"end\"\n {...otherProps}\n onClick={combineEventHandlers(handleAction, onClick as never)}\n disabled={shouldDisable}\n loading={loading || submitting}\n enabledWhenLoading={enabledWhenLoading}\n >\n {label}\n </Button>\n </AlertDialogTrigger>\n\n <AlertDialogContent\n color=\"primary\"\n {...dialogContentProps}\n portalProps={{\n container: formAppEl,\n ...dialogContentProps?.portalProps,\n }}\n >\n {submissionInfo && (\n <>\n <AlertDialogHeader {...dialogHeaderProps}>\n <AlertDialogTitle {...dialogTitleProps}>\n {typeof dialogTitle === \"function\"\n ? dialogTitle(submissionInfo.value, submissionInfo.warnings)\n : dialogTitle}\n </AlertDialogTitle>\n </AlertDialogHeader>\n\n <AlertDialogBody {...dialogBodyProps}>\n <Stack gap={3}>\n {dialogDescription && (\n <AlertDialogDescription\n {...dialogDescriptionProps}\n style={{ margin: 0, ...dialogDescriptionProps?.style }}\n className={cx(\n prefix(\"submit-action__dialog-description\"),\n dialogDescriptionProps?.className,\n )}\n >\n {typeof dialogDescription === \"function\"\n ? dialogDescription(\n submissionInfo.value,\n submissionInfo.warnings,\n )\n : dialogDescription}\n </AlertDialogDescription>\n )}\n\n {typeof dialogBody === \"function\"\n ? dialogBody(submissionInfo.value, submissionInfo.warnings)\n : dialogBody}\n\n {confirmWarnings &&\n (submissionInfo.warnings?.length ?? 0) > 0 && (\n <Alert\n severity=\"warning\"\n {...confirmWarningsAlertProps}\n className={cx(\n prefix(\"submit-action__confirm-warnings-alert\"),\n confirmWarningsAlertProps?.className,\n )}\n >\n <Checkbox\n status=\"warned\"\n {...confirmWarningsCheckboxProps}\n checked={allWarningsChecked}\n onCheckedChange={handleOnCheckedChange}\n >\n {confirmWarningsCheckboxLabel}\n </Checkbox>\n </Alert>\n )}\n </Stack>\n </AlertDialogBody>\n\n <AlertDialogFooter {...dialogFooterProps}>\n <AlertDialogCancel disabled={runningOnSubmit}>\n <Button variant=\"subtle\" {...dialogCancelButtonProps}>\n {dialogCancelText}\n </Button>\n </AlertDialogCancel>\n\n <AlertDialogAction onClick={handleConfirmSubmit}>\n <Button\n type=\"submit\"\n color=\"primary\"\n icon={faArrowRight}\n iconPlacement=\"end\"\n {...dialogOkButtonProps}\n loading={runningOnSubmit || dialogOkButtonProps?.loading}\n disabled={\n (confirmWarnings && !allWarningsChecked) ||\n dialogOkButtonProps?.disabled\n }\n >\n {dialogOkText}\n </Button>\n </AlertDialogAction>\n </AlertDialogFooter>\n </>\n )}\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n","import type { AbsolutePath, Table, TableRowId } from \"@ostack.tech/kform\";\nimport type { FormatterController } from \"@ostack.tech/kform-react\";\nimport { createContext, type Ref, useContext } from \"react\";\n\nimport type { UseRegisterControlResult } from \"../../utils/useRegisterControl.tsx\";\nimport type { TableControlRowController } from \"./TableControlColumn.tsx\";\n\n/** Value of the table control context. */\nexport interface TableControlContextValue<\n T = any,\n TTable extends Table<T> | null = Table<T> | null,\n> {\n controller: TableControlController<T, TTable>;\n autofocusRef: Ref<HTMLDivElement>;\n handleFocus: UseRegisterControlResult<HTMLDivElement>[\"handleFocus\"];\n size?: number;\n maxRows?: number;\n}\n\n/** Controller of the table control. */\nexport type TableControlController<\n T = any,\n TTable extends Table<T> | null = Table<T> | null,\n> = FormatterController<TTable, TableRowId[]> & {\n addRow: () => PromiseLike<void> | void;\n removeRow: (path: AbsolutePath) => PromiseLike<void> | void;\n};\n\n/** Table control context. */\nexport const TableControlContext =\n createContext<TableControlContextValue | null>(null);\n\n/** Hook providing access to the table control context. */\nexport function useTableControlContext<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>(): TableControlContextValue<T, TTable> {\n const tableControlContext = useContext(TableControlContext);\n if (!tableControlContext) {\n throw new Error(\"Table control context not in scope.\");\n }\n return tableControlContext as unknown as TableControlContextValue<T, TTable>;\n}\n\n/** Table control row context. */\nexport const TableControlRowContext =\n createContext<TableControlRowController | null>(null);\n\n/** Hook providing access to the table control row context. */\nexport function useTableControlRowContext<T>(): TableControlRowController<T> {\n const tableControlRowContext = useContext(TableControlRowContext);\n if (!tableControlRowContext) {\n throw new Error(\"Table control row context not in scope.\");\n }\n return tableControlRowContext as TableControlRowController<T>;\n}\n","import { DataTableCell, usePrinting } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useDeferredValue,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useTableControlRowContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control cell. */\nexport interface TableControlCellProps extends ComponentPropsWithoutRef<\n typeof DataTableCell\n> {}\n\n/** Cell of the table control. */\nexport const TableControlCell = forwardRef<\n ComponentRef<typeof DataTableCell>,\n TableControlCellProps\n>(function TableControlCell({ variant, ...otherProps }, forwardedRef) {\n const printing = usePrinting();\n const { useDisplayStatus } = useTableControlRowContext();\n const deferredDisplayStatus = useDeferredValue(useDisplayStatus());\n return (\n <DataTableCell\n variant={variant}\n // When the cell has a \"header\" variant, set its status from the row's\n // display status\n status={\n !printing && variant === \"header\"\n ? displayStatusToControlStatus(deferredDisplayStatus)\n : undefined\n }\n {...otherProps}\n ref={forwardedRef}\n />\n );\n});\n","import { CurrentPath, useController } from \"@ostack.tech/kform-react\";\nimport { DataTableRow, useStartPrintingTask } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n memo,\n useEffect,\n useMemo,\n} from \"react\";\n\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterController, useRegisterLabel } from \"../FormApp\";\nimport { TableControlRowContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control row. */\nexport interface TableControlRowProps extends ComponentPropsWithoutRef<\n typeof DataTableRow\n> {}\n\n/** Row of a table control. */\nexport const TableControlRow = memo(\n forwardRef<ComponentRef<typeof DataTableRow>, TableControlRowProps>(\n function TableControlRow({ row, index, ...otherProps }, forwardedRef) {\n const controller = useController(row, {\n enabled: !useFormIsLoading() && row != null,\n });\n const path = controller.usePath();\n useRegisterController(controller);\n useRegisterLabel(path, row == null ? null : index + 1);\n\n // Start a printing task until the row is initialised\n const initialized = controller.useInitialized();\n const finishPrintingTask = useStartPrintingTask({ enabled: row != null });\n useEffect(() => {\n if (initialized) {\n finishPrintingTask();\n }\n }, [finishPrintingTask, initialized]);\n\n return (\n <CurrentPath path={path}>\n <TableControlRowContext.Provider\n value={useMemo(\n () => ({ index, ...controller }),\n [controller, index],\n )}\n >\n <DataTableRow\n row={row}\n index={index}\n {...otherProps}\n ref={forwardedRef}\n />\n </TableControlRowContext.Provider>\n </CurrentPath>\n );\n },\n ),\n);\n","import {\n AbsolutePath,\n AbsolutePathFragment,\n arrayToTable,\n type CancellablePromise,\n indexOfTableRowId,\n isComputedSchema,\n type Path,\n sliceTable,\n type Table,\n type TableRowId,\n} from \"@ostack.tech/kform\";\nimport {\n type ControllerOptions,\n InvalidPathError,\n useFormatter,\n} from \"@ostack.tech/kform-react\";\nimport {\n cx,\n DataTable,\n type DataTableColumns,\n type DataTableContent,\n type DataTableScrollToOptions,\n useDataTableApiRef,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useImperativeHandle,\n useMemo,\n useState,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport { FormAppStatus, useOnPathFocus } from \"../FormApp\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\nimport type { TableControlApi } from \"./TableControlApi.ts\";\nimport { TableControlCell } from \"./TableControlCell.tsx\";\nimport type {\n TableControlColumn,\n TableControlColumns,\n TableControlStatus,\n} from \"./TableControlColumn.tsx\";\nimport {\n TableControlContext,\n useTableControlRowContext,\n} from \"./TableControlContext.ts\";\nimport { TableControlRow } from \"./TableControlRow.tsx\";\n\n/** Properties of the table control component. */\nexport interface TableControlProps<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>\n extends\n Omit<\n ComponentPropsWithoutRef<typeof DataTable>,\n | \"columns\"\n | \"rows\"\n | \"getRows\"\n | \"rowKey\"\n | \"loading\"\n | \"defaultFilter\"\n | \"filter\"\n | \"onFilterChange\"\n | \"defaultSortBy\"\n | \"sortBy\"\n | \"defaultSortDirection\"\n | \"sortDirection\"\n | \"onSort\"\n | \"showSelectionColumn\"\n | \"defaultSelectedRows\"\n | \"selectedRows\"\n | \"onSelectedRowsChange\"\n | \"showAllRowsWhilePrinting\"\n | \"apiRef\"\n >,\n Omit<ControllerOptions<TTable>, \"enabled\"> {\n /** Control's path. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this table.\n *\n * This label has priority over the table's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /** Table control columns. */\n columns: TableControlColumns<T>;\n /**\n * Sets the maximum number of rows that the table can have. By default, if the\n * table's schema has a `MaxSize` validation, then its value is used.\n */\n maxRows?: number;\n /** Sets the table control as disabled. */\n disabled?: boolean;\n /** Sets the table control as read-only. */\n readOnly?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control to\n * be focused when the form app's `focus` is called with this control's path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<TableControlApi<T, TTable> | undefined>;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\" | \"unwrapped\"\n >;\n}\n\n/** Table control component supporting (possibly nullable) collection schemas. */\nexport const TableControl = forwardRef(function TableControl<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n apiRef,\n issueMessagesProps,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n columns,\n required,\n maxRows,\n disabled = false,\n readOnly = false,\n className,\n ...otherProps\n }: TableControlProps<T, TTable>,\n forwardedRef: ForwardedRef<ComponentRef<typeof DataTableContent>>,\n) {\n const prefix = usePrefix();\n const [ids, setIds] = useState<TableRowId[] | undefined>(undefined);\n const size = ids?.length;\n const dataTableApiRef = useDataTableApiRef();\n\n const controller = useFormatter<TTable, TableRowId[]>(path, {\n enabled: !useFormIsLoading(),\n format: useCallback(\n (value?: TTable) => (value ? sliceTable(value).map(([id]) => id) : []),\n [],\n ),\n setFormattedValue: setIds,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n\n const { useSchema, usePath, useInitialized, useExists } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const initialized = useInitialized();\n const exists = useExists();\n const { restrictions } = schema.typeInfo;\n const maxRowsRestriction =\n maxRows ??\n (typeof restrictions.maxSize === \"number\"\n ? restrictions.maxSize\n : undefined);\n const elementsSchema = controller.useState((state) =>\n state.formManager.schema(state.path.append(AbsolutePathFragment.Wildcard)),\n );\n\n if (schema.typeInfo.name !== \"Table\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected (possibly nullable) table schema, \" +\n \"but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n const ownController = useMemo(\n () => ({\n addRow: async () => {\n const { schema, initialized, exists, touched, dirty } =\n controller.getState();\n if (\n !initialized ||\n !exists ||\n (maxRowsRestriction != null && size! >= maxRowsRestriction)\n ) {\n return;\n }\n\n const initialRowValue = elementsSchema.initialValue;\n const setPromise: CancellablePromise<void> =\n schema.typeInfo.nullable && size === 0\n ? controller.set(arrayToTable([initialRowValue]) as TTable)\n : controller.set(\"-\", initialRowValue);\n setPromise.then(\n () =>\n void Promise.resolve().then(() =>\n dataTableApiRef.current!.goTo(size!),\n ),\n );\n\n if (!touched) {\n void controller.setTouched();\n }\n if (!dirty) {\n void controller.setDirty();\n }\n return setPromise;\n },\n removeRow: (path: AbsolutePath) => {\n const { formManager, schema, initialized, exists, touched, dirty } =\n controller.getState();\n if (!initialized || !exists) {\n return;\n }\n\n const removePromise =\n schema.typeInfo.nullable && size === 1\n ? controller.set(null as TTable)\n : formManager.remove(path);\n\n if (!touched) {\n void controller.setTouched();\n }\n if (!dirty) {\n void controller.setDirty();\n }\n return removePromise;\n },\n }),\n [\n maxRowsRestriction,\n controller,\n dataTableApiRef,\n elementsSchema.initialValue,\n size,\n ],\n );\n\n // Expose the control's API via `apiRef`\n const goToIndex = useCallback(\n (index: number, scrollOptions?: DataTableScrollToOptions) => {\n dataTableApiRef.current?.goTo(index, scrollOptions);\n },\n [dataTableApiRef],\n );\n const goToId = useCallback(\n (id: number, scrollOptions?: DataTableScrollToOptions) => {\n const { initialized, exists } = controller.getState();\n if (initialized && exists) {\n void controller.get((value) => {\n if (value) {\n const idx = indexOfTableRowId(value, id);\n if (idx !== -1) {\n dataTableApiRef.current?.goTo(idx, scrollOptions);\n }\n }\n });\n }\n },\n [controller, dataTableApiRef],\n );\n\n // Register the control\n const {\n displayDisabled,\n displayReadOnly,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl<TTable, HTMLDivElement>({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n });\n const controlIsDisabled = displayDisabled || disabled;\n const controlIsReadOnly =\n displayReadOnly || readOnly || isComputedSchema(schema);\n\n useImperativeHandle(\n apiRef,\n () => ({\n ...controller,\n goToIndex,\n goToId,\n }),\n [controller, goToId, goToIndex],\n );\n\n // Go to row with active path when it changes\n useOnPathFocus(\n useCallback(\n (focusedPath) => {\n if (\n exists &&\n focusedPath &&\n absolutePath.resolve(AbsolutePath.DESCENDANTS).contains(focusedPath)\n ) {\n const rowId = focusedPath.fragments[absolutePath.size];\n if (rowId instanceof AbsolutePathFragment.Id) {\n goToId(+rowId.id, { align: \"center\", behavior: \"smooth\" });\n }\n }\n },\n [absolutePath, exists, goToId],\n ),\n );\n\n const printing = usePrinting();\n const dataTableColumns: DataTableColumns<AbsolutePath> = useMemo(\n () =>\n tableControlToDataTableColumns(columns, {\n disabled: controlIsDisabled,\n readOnly: controlIsReadOnly,\n printing,\n }),\n [columns, controlIsDisabled, controlIsReadOnly, printing],\n );\n\n const tableControlController = useMemo(\n () => ({ ...controller, ...ownController }),\n [controller, ownController],\n );\n\n const [inlineIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n return (\n <FormAppStatus disabled={controlIsDisabled} readOnly={controlIsReadOnly}>\n <TableControlContext.Provider\n value={{\n controller: tableControlController as never,\n autofocusRef,\n handleFocus,\n size,\n maxRows: maxRowsRestriction,\n }}\n >\n <DataTable\n className={cx(prefix(\"table-control\"), className)}\n displayMode=\"scrolled\"\n columns={dataTableColumns}\n rows={ids}\n rowKey={(id: TableRowId) => id}\n required={required ?? restrictions.required === true}\n loading={!initialized}\n renderRow={(props) => <TableControlRow {...props} />}\n renderCell={(props) => <TableControlCell {...props} />}\n showAllRowsWhilePrinting\n apiRef={dataTableApiRef}\n {...otherProps}\n ref={forwardedRef}\n />\n {inlineIssues}\n </TableControlContext.Provider>\n </FormAppStatus>\n );\n});\n\nfunction tableControlToDataTableColumns<T>(\n columns: TableControlColumns<T>,\n tableControlStatus: TableControlStatus,\n columnNamePrefix = \"col\",\n): DataTableColumns<AbsolutePath> {\n return columns.reduce(\n (dataColumns: DataTableColumns<AbsolutePath>, dataColumnOrFn, i) => {\n const dataColumn =\n typeof dataColumnOrFn === \"function\"\n ? dataColumnOrFn(tableControlStatus)\n : dataColumnOrFn;\n if (dataColumn) {\n const { subColumns, render, ...otherColumn } = dataColumn;\n dataColumns[`${columnNamePrefix}-${i}`] = {\n ...otherColumn,\n subColumns:\n subColumns &&\n tableControlToDataTableColumns(\n subColumns,\n tableControlStatus,\n `${columnNamePrefix}-${i}`,\n ),\n filterable: false,\n render:\n render && (() => <TableControlCellRenderer render={render} />),\n };\n }\n return dataColumns;\n },\n {},\n );\n}\n\n/** Properties of the table control cell renderer. */\nexport interface TableControlCellRendererProps<T = unknown> {\n render: NonNullable<TableControlColumn<T>[\"render\"]>;\n}\n\n/** Renderer of a table control cell. */\nexport function TableControlCellRenderer<T = unknown>({\n render,\n}: TableControlCellRendererProps<T>) {\n const controller = useTableControlRowContext<T>();\n return render(controller);\n}\n","import { faPlus } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n Button,\n combineEventHandlers,\n cx,\n Slot,\n usePrintClassNames,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useFormIsDisabled, useFormIsReadOnly } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport { useTableControlContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control add row trigger component. */\nexport interface TableControlAddRowTriggerProps extends ComponentPropsWithoutRef<\n typeof Button\n> {\n /**\n * Text displayed on the button rendered by default when no `children` are\n * provided. If `children` are provided, this property has no effect.\n */\n defaultButtonText?: ReactNode;\n /** Function called after the row has been added. */\n onRowAdded?: () => void;\n /**\n * Whether to show the trigger when the table is read-only.\n *\n * @default false\n */\n showWhenReadOnly?: boolean;\n /**\n * Whether to show the trigger when it is being printed.\n *\n * @default false\n */\n showWhilePrinting?: boolean;\n}\n\n/**\n * Trigger used to add a new row to a table control.\n *\n * By default, it renders a button with text `defaultButtonText`, however, this\n * can be overriden by providing `children`.\n */\nexport const TableControlAddRowTrigger = forwardRef<\n ComponentRef<typeof Button>,\n TableControlAddRowTriggerProps\n>(function TableControlAddRowTrigger(\n {\n defaultButtonText,\n onRowAdded,\n showWhenReadOnly,\n showWhilePrinting,\n disabled,\n onClick,\n className,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const [locale] = useLocale();\n defaultButtonText ??= locale.TableControlAddRowTrigger.defaultButtonText;\n\n const { printHidden } = usePrintClassNames();\n const { controller, size, maxRows } = useTableControlContext();\n const controlIsDisabled = useFormIsDisabled();\n const controlIsReadOnly = useFormIsReadOnly();\n const setLatestInteraction = useSetLatestInteraction();\n\n const handleClick = async () => {\n await controller.addRow();\n setLatestInteraction(controller.getState().path);\n onRowAdded?.();\n };\n\n const shouldDisable = controller.useState(\n ({ initialized, exists }) =>\n !initialized ||\n !exists ||\n controlIsDisabled ||\n disabled ||\n controlIsReadOnly ||\n (maxRows != null && size! >= maxRows),\n );\n\n const As: any = Slot;\n return (\n (showWhenReadOnly || !controlIsReadOnly) && (\n <As\n className={cx(\n prefix(\"table-control__add-row-trigger\"),\n showWhilePrinting || printHidden,\n className,\n )}\n disabled={shouldDisable}\n onClick={combineEventHandlers(onClick, handleClick, {\n checkDefaultPrevented: true,\n })}\n {...otherProps}\n ref={forwardedRef}\n >\n {children ?? (\n <Button icon={faPlus} color=\"primary\">\n {defaultButtonText}\n </Button>\n )}\n </As>\n )\n );\n});\n","import type { Table, TableRowId } from \"@ostack.tech/kform\";\nimport type { Controller } from \"@ostack.tech/kform-react\";\nimport type { DataTableScrollToOptions } from \"@ostack.tech/ui\";\nimport { type RefObject, useRef } from \"react\";\n\n/** Imperative table control API. */\nexport type TableControlApi<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n> = Controller<TTable> & {\n /**\n * Navigates to the row with the provided index.\n *\n * @param index Index of row to navigate to.\n * @param scrollOptions Options used to configure to scrolling to the row\n * (only relevant in scrolled display mode).\n */\n goToIndex: (index: number, scrollOptions?: DataTableScrollToOptions) => void;\n /**\n * Navigates to the row with the provided id.\n *\n * @param id Id of row to navigate to.\n * @param scrollOptions Options used to configure to scrolling to the row\n * (only relevant in scrolled display mode).\n */\n goToId: (id: TableRowId, scrollOptions?: DataTableScrollToOptions) => void;\n};\n\n/** Hook used to access the table control API. */\nexport function useTableControlApiRef<\n T = unknown,\n TTable extends Table<T> | null = Table<T> | null,\n>(): RefObject<TableControlApi<T, TTable> | null> {\n return useRef<TableControlApi<T, TTable>>(null);\n}\n","import { faTrash } from \"@fortawesome/free-solid-svg-icons\";\nimport {\n combineEventHandlers,\n IconButton,\n Slot,\n useAlertDialog,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n type ReactNode,\n useState,\n} from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsDisabled, useFormIsReadOnly } from \"../FormApp\";\nimport { useSetLatestInteraction } from \"../FormApp/FormAppContext.ts\";\nimport {\n useTableControlContext,\n useTableControlRowContext,\n} from \"./TableControlContext.ts\";\n\n/** Properties of the table control remove row trigger component. */\nexport interface TableControlRemoveRowTriggerProps extends Omit<\n Partial<ComponentPropsWithoutRef<typeof IconButton>>,\n \"children\"\n> {\n /**\n * Whether to show a confirmation message when removing a row.\n *\n * @default false\n */\n showConfirmation?: boolean;\n /**\n * Function called after confirmation that the row is to be removed (this\n * function is called even if `showConfirmation` is not set).\n */\n onConfirmRowRemoval?: () => void;\n /** Function called after the row has been removed. */\n onRowRemoved?: () => void;\n /**\n * Label displayed on the icon button rendered by default when no `children`\n * are provided. If `children` are provided, this property has no effect.\n */\n defaultButtonLabel?: ReactNode;\n /** Title of the confirmation dialog when `showConfirmation` is `true`. */\n confirmDialogTitle?: ReactNode;\n /**\n * Message of the confirmation dialog when `showConfirmation` is `true`.\n *\n * @param index Index of the row being removed.\n */\n confirmDialogMessage?: (index: number) => ReactNode;\n /**\n * Ok button text of the confirmation dialog when `showConfirmation` is\n * `true`.\n */\n confirmDialogOkText?: ReactNode;\n /**\n * Cancel button text of the confirmation dialog when `showConfirmation` is\n * `true`.\n */\n confirmDialogCancelText?: ReactNode;\n /**\n * Whether to show the trigger when the table is read-only.\n *\n * @default false\n */\n showWhenReadOnly?: boolean;\n /**\n * Children of the remove row trigger component. By default, it is an\n * `IconButton` with label `defaultButtonLabel`. A function can be optionally\n * passed as children which will receive an argument with whether the row is\n * currently being removed.\n */\n children?: ReactNode;\n}\n\n/**\n * Trigger used to remove a row of a table controlled by a table control.\n *\n * By default, it renders an icon button with label `defaultButtonLabel`,\n * however, this can be overriden by providing `children`.\n */\nexport const TableControlRemoveRowTrigger = forwardRef<\n ComponentRef<typeof IconButton>,\n TableControlRemoveRowTriggerProps\n>(function TableControlRemoveRowTrigger(\n {\n showConfirmation,\n onConfirmRowRemoval,\n onRowRemoved,\n defaultButtonLabel,\n confirmDialogTitle,\n confirmDialogMessage,\n confirmDialogOkText,\n confirmDialogCancelText,\n showWhenReadOnly,\n disabled,\n onClick,\n children,\n ...otherProps\n },\n forwardedRef,\n) {\n const [locale] = useLocale();\n defaultButtonLabel ??= locale.TableControlRemoveRowTrigger.defaultButtonLabel;\n confirmDialogTitle ??= locale.TableControlRemoveRowTrigger.confirmDialogTitle;\n confirmDialogMessage ??=\n locale.TableControlRemoveRowTrigger.confirmDialogMessage;\n confirmDialogOkText ??=\n locale.TableControlRemoveRowTrigger.confirmDialogOkText;\n confirmDialogCancelText ??=\n locale.TableControlRemoveRowTrigger.confirmDialogCancelText;\n\n const { confirm } = useAlertDialog();\n const { controller } = useTableControlContext();\n const controlIsDisabled = useFormIsDisabled();\n const controlIsReadOnly = useFormIsReadOnly();\n const { getState, index, useInitialized, useExists } =\n useTableControlRowContext();\n const initialized = useInitialized();\n const exists = useExists();\n const setLatestInteraction = useSetLatestInteraction();\n\n const [removing, setRemoving] = useState(false);\n const handleClick = async () => {\n const { path, dirty } = getState();\n if (\n removing ||\n (showConfirmation &&\n dirty &&\n !(await confirm(confirmDialogMessage!(index), {\n title: confirmDialogTitle,\n color: \"danger\",\n okText: confirmDialogOkText,\n cancelText: confirmDialogCancelText,\n })))\n ) {\n return;\n }\n\n setRemoving(true);\n onConfirmRowRemoval?.();\n await controller.removeRow(path);\n setLatestInteraction(controller.getState().path);\n onRowRemoved?.();\n };\n\n const As: any = Slot;\n return (\n (showWhenReadOnly || !controlIsReadOnly) && (\n <As\n {...otherProps}\n disabled={\n !initialized ||\n !exists ||\n controlIsDisabled ||\n disabled ||\n controlIsReadOnly ||\n removing\n }\n onClick={combineEventHandlers(onClick, handleClick, {\n checkDefaultPrevented: true,\n })}\n ref={forwardedRef}\n >\n {children ?? (\n <IconButton\n icon={faTrash}\n label={defaultButtonLabel}\n color=\"danger\"\n loading={!initialized || removing}\n circle\n />\n )}\n </As>\n )\n );\n});\n","import type { Controller } from \"@ostack.tech/kform-react\";\nimport type { DataTableColumn } from \"@ostack.tech/ui\";\nimport type { ComponentPropsWithRef, ReactNode } from \"react\";\n\nimport { TableControlRemoveRowTrigger } from \"./TableControlRemoveRowTrigger.tsx\";\n\n/** Array of table control columns. */\nexport type TableControlColumns<T = unknown> = (\n | TableControlColumn<T>\n | ((\n tableControlStatus: TableControlStatus,\n ) => TableControlColumn<T> | false | null | undefined)\n | false\n | null\n | undefined\n)[];\n\n/** Status of the table control. */\nexport interface TableControlStatus {\n /** Whether the table control is disabled. */\n disabled: boolean;\n /** Whether the table control is read-only. */\n readOnly: boolean;\n /** Whether the table is being printed. */\n printing: boolean;\n}\n\n/** Controller of a table row. */\nexport type TableControlRowController<T = unknown> = Controller<T> & {\n /** Row index. */\n index: number;\n};\n\n/** Column of a table control. */\n\nexport interface TableControlColumn<T = unknown, TValue = any> extends Omit<\n DataTableColumn<T, TValue>,\n | \"subColumns\"\n | \"getValue\"\n | \"format\"\n | \"render\"\n | \"compare\"\n | \"filterable\"\n | \"sortable\"\n> {\n /** Sub columns of this column. */\n subColumns?: TableControlColumns<T>;\n /** Function used to render the cell's content. */\n render?: (rowController: TableControlRowController<T>) => ReactNode;\n}\n\n/**\n * Pre-configured column used to display the index of each row. By default, it\n * sticks to left of the table.\n *\n * @param overrides Column properties to override the defaults.\n * @returns Table control column used to display the index of each row.\n */\n\nexport function tableControlIndexColumn<T = unknown, TValue = any>(\n overrides?: TableControlColumn<T, TValue>,\n): TableControlColumn<T, TValue> {\n return {\n label: \"#\",\n header: true,\n sticky: \"left\",\n width: 65,\n fixed: true,\n align: \"center\",\n render: ({ index }) => index + 1,\n ...overrides,\n } as TableControlColumn<T, TValue>;\n}\n\n/**\n * Pre-configured column used to display row actions. By default, it sticks to\n * the right of the table and renders the `TableControlRemoveRow` component.\n *\n * Its configuration can be overriden to show other actions, for example, an\n * edit button:\n *\n * ```tsx\n * tableControlActionsColumn({\n * width: 100,\n * render: () => (\n * <>\n * <IconButton label=\"Edit row\" icon={faPencil} />\n * <TableControlRemoveRow />\n * </>\n * ),\n * });\n * ```\n *\n * @param overrides Column properties used to display the actions of each row.\n * @returns Table control column used to display the actions of each row.\n */\n\nexport function tableControlActionsColumn<T = unknown, TValue = any>({\n removeRowProps,\n ...columnOverrides\n}: TableControlColumn<T, TValue> & {\n removeRowProps?: ComponentPropsWithRef<typeof TableControlRemoveRowTrigger>;\n} = {}): (\n tableControlStatus: TableControlStatus,\n) => TableControlColumn<T, TValue> | false {\n return (tableControlStatus: TableControlStatus) =>\n !tableControlStatus.readOnly &&\n !tableControlStatus.printing &&\n ({\n sticky: \"right\",\n width: 50,\n fixed: true,\n align: \"center\",\n render: () => <TableControlRemoveRowTrigger {...removeRowProps} />,\n ...columnOverrides,\n } as TableControlColumn<T, TValue>);\n}\n","import {\n combineEventHandlers,\n cx,\n DataTableContent,\n useCombinedRef,\n usePrinting,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useDeferredValue,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useTableControlContext } from \"./TableControlContext.ts\";\n\n/** Properties of the table control content component. */\nexport interface TableControlContentProps extends Omit<\n ComponentPropsWithoutRef<typeof DataTableContent>,\n \"status\"\n> {}\n\n/** Component containing the content of the table control. */\nexport const TableControlContent = forwardRef<\n ComponentRef<typeof DataTableContent>,\n TableControlContentProps\n>(function TableControlContent(\n { containerProps, ...otherProps },\n forwardedRef,\n) {\n const prefix = usePrefix();\n const { autofocusRef, handleFocus, controller } = useTableControlContext();\n\n const handleContainerOnBlur = useCallback(() => {\n const { initialized, exists, touched } = controller.getState();\n if (initialized && exists && touched) {\n void controller.setTouched();\n }\n }, [controller]);\n\n const printing = usePrinting();\n const deferredDisplayStatus = useDeferredValue(controller.useDisplayStatus());\n return (\n <DataTableContent\n editable\n variant=\"control\"\n status={\n printing\n ? undefined\n : displayStatusToControlStatus(deferredDisplayStatus)\n }\n containerProps={{\n ...containerProps,\n className: cx(\n prefix(\"table-control__content-container\"),\n containerProps?.className,\n ),\n onFocus: combineEventHandlers(containerProps?.onFocus, handleFocus),\n onBlur: combineEventHandlers(\n containerProps?.onBlur,\n handleContainerOnBlur,\n ),\n ref: useCombinedRef(autofocusRef, containerProps?.ref),\n }}\n {...otherProps}\n ref={forwardedRef}\n />\n );\n});\n","import { DataTablePagination } from \"@ostack.tech/ui\";\n\n/** Table control pagination. */\nexport const TableControlPagination = DataTablePagination;\n","import { DataTableRowsPerPage } from \"@ostack.tech/ui\";\n\n/** Table control rows per page. */\nexport const TableControlRowsPerPage = DataTableRowsPerPage;\n","import type { Path } from \"@ostack.tech/kform\";\nimport {\n type FormatterControllerState,\n type InputController,\n type InputOptions,\n InvalidPathError,\n useInput,\n} from \"@ostack.tech/kform-react\";\nimport {\n combineEventHandlers,\n Input,\n TextArea,\n useCombinedRef,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentRef,\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type Ref,\n useEffect,\n useRef,\n} from \"react\";\n\nimport { displayStatusToControlStatus } from \"../../utils/displayStatusConversions.ts\";\nimport { useControlIssues } from \"../../utils/useControlIssues.tsx\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport { useRegisterControl } from \"../../utils/useRegisterControl.tsx\";\nimport type { IssueMessages, IssueMessagesByCode } from \"../IssueMessages\";\n\n/** Properties of the text control component. */\nexport type TextControlProps<T extends string | null = string | null> =\n | TextControlPropsSingleline<T>\n | TextControlPropsMultiline<T>;\n\nexport type TextControlPropsSingleline<\n T extends string | null = string | null,\n> = Omit<\n ComponentPropsWithoutRef<typeof Input>,\n \"defaultValue\" | \"value\" | \"status\"\n> &\n TextControlPropsBase<T> & {\n multiline?: false;\n };\n\nexport type TextControlPropsMultiline<T extends string | null = string | null> =\n Omit<\n ComponentPropsWithoutRef<typeof TextArea>,\n \"defaultValue\" | \"value\" | \"status\"\n > &\n TextControlPropsBase<T> & {\n multiline: true;\n pattern?: never;\n };\n\nexport type TextControlPropsBase<T extends string | null = string | null> =\n Omit<\n InputOptions<T, string, ComponentRef<typeof Input | typeof TextArea>>,\n \"enabled\" | \"format\" | \"parse\"\n > & {\n /** Path to the value. */\n path?: string | Path;\n /**\n * Issue messages of this control.\n *\n * Mapping from an issue's code to its message.\n */\n issueMessages?: IssueMessagesByCode;\n /**\n * Label to use in the issues panel when displaying issues associated with\n * this field.\n *\n * This label has priority over the field's `ControlLabel`.\n */\n issuesPanelLabel?: ReactNode;\n /**\n * Whether to display the issues associated with this control.\n *\n * @default true\n */\n displayIssues?: boolean;\n /**\n * Whether to prevent the auto-focusing behaviour that causes this control\n * to be focused when the form app's `focus` is called with this control's\n * path.\n *\n * Preventing this behaviour is useful when multiple controls for the same\n * path are rendered at once, and only one of them should be focused.\n *\n * @default false\n */\n preventAutoFocus?: boolean;\n /** Whether to render a multiline text control. */\n multiline?: boolean;\n /** Reference to the control's API. */\n apiRef?: Ref<\n | InputController<T, string, ComponentRef<typeof Input | typeof TextArea>>\n | undefined\n >;\n /** Properties to pass to the `IssueMessages` component. */\n issueMessagesProps?: Omit<\n ComponentPropsWithRef<typeof IssueMessages>,\n \"path\" | \"issues\" | \"messages\"\n >;\n };\n\n/**\n * Text control component supporting (possibly nullable) schemas of type\n * \"String\".\n *\n * If the schema is nullable, this component sets the form value to `null` when\n * the control is empty. Note, however, that the form may still hold an empty\n * string as value if set programmatically.\n *\n * The component further supports either single or multiple lines via the\n * `multiline` prop.\n */\nexport const TextControl = forwardRef(function TextControl<\n T extends string | null = string | null,\n>(\n {\n path,\n issueMessages,\n issuesPanelLabel,\n displayIssues = true,\n preventAutoFocus,\n multiline,\n apiRef,\n issueMessagesProps,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n required,\n minLength,\n maxLength,\n pattern,\n loading,\n disabled,\n readOnly,\n endAdornment,\n onChange,\n onFocus,\n onBlurToOutside,\n ...otherProps\n }: TextControlProps<T>,\n forwardedRef: ForwardedRef<ComponentRef<\"input\" | \"textarea\">>,\n) {\n const controller = useInput<T, string, ComponentRef<typeof Input>>(path, {\n enabled: !useFormIsLoading(),\n parse: parseText,\n formManager,\n onInitialized,\n onFormManagerEvent,\n onValueChange,\n onValidationStatusChange,\n onDisplayStatusChange,\n onDirtyStatusChange,\n onTouchedStatusChange,\n });\n const { useSchema, usePath, inputProps } = controller;\n const schema = useSchema();\n const absolutePath = usePath();\n const { restrictions } = schema.typeInfo;\n\n if (schema.typeInfo.name !== \"String\") {\n throw new InvalidPathError(\n absolutePath,\n \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n \"strings, but got schema representing values of type \" +\n `'${schema.typeInfo.toString()}'.`,\n );\n }\n\n // Register the control\n const {\n displayLoading,\n displayDisabled,\n displayReadOnly,\n displayStatusToDisplay,\n issuesToDisplay,\n autofocusRef,\n handleFocus,\n } = useRegisterControl({\n controller,\n issuesPanelLabel,\n ariaLabel: otherProps[\"aria-label\"],\n preventAutoFocus,\n apiRef,\n });\n\n const prevMultiline = useRef(multiline);\n useEffect(() => {\n if (prevMultiline.current !== multiline) {\n throw new Error(\n \"The `multiline` property cannot not be changed at runtime.\",\n );\n }\n }, [multiline]);\n\n const [inlineIssues, popoverIssues] = useControlIssues({\n issuesToDisplay: {\n [absolutePath.toString()]: issuesToDisplay,\n },\n issueMessages: { [absolutePath.toString()]: issueMessages },\n displayIssues,\n issueMessagesProps,\n });\n\n const commonProps: ComponentPropsWithRef<typeof Input | typeof TextArea> = {\n name: inputProps.name,\n required: required ?? restrictions.required === true,\n minLength:\n minLength ??\n (typeof restrictions.minLength === \"number\"\n ? restrictions.minLength\n : undefined),\n maxLength:\n maxLength ??\n (typeof restrictions.maxLength === \"number\"\n ? restrictions.maxLength\n : undefined),\n pattern:\n pattern ??\n (typeof restrictions.pattern === \"string\"\n ? restrictions.pattern\n : undefined),\n loading: displayLoading || loading,\n disabled: displayDisabled || disabled,\n readOnly: displayReadOnly || readOnly || inputProps.readOnly,\n status: displayStatusToControlStatus(displayStatusToDisplay),\n endAdornment: (\n <>\n {popoverIssues}\n {endAdornment}\n </>\n ),\n onChange: combineEventHandlers(onChange as never, inputProps.onChange),\n onFocus: combineEventHandlers(onFocus as never, handleFocus),\n onBlurToOutside: combineEventHandlers(\n onBlurToOutside as never,\n inputProps.onBlur,\n ),\n ref: useCombinedRef(\n inputProps.ref,\n useCombinedRef(autofocusRef, forwardedRef),\n ) as never,\n ...otherProps,\n };\n return (\n <>\n {multiline ? (\n <TextArea\n {...(commonProps as ComponentPropsWithRef<typeof TextArea>)}\n />\n ) : (\n <Input\n type=\"text\"\n {...(commonProps as ComponentPropsWithRef<typeof Input>)}\n />\n )}\n {inlineIssues}\n </>\n );\n});\n\n/** Parses a text control formatted value. */\nfunction parseText<T extends string | null>(\n formattedValue: string,\n state: FormatterControllerState<T, string>,\n): T {\n return (\n state.schema.typeInfo.nullable ? formattedValue || null : formattedValue\n ) as T;\n}\n","import {\n cx,\n PortalContext,\n useCombinedRef,\n useMeasure,\n usePrintClassNames,\n} from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\nimport { useSetTopBarHeight } from \"../FormApp\";\n\n/** Properties of the top bar component. */\nexport interface TopBarProps extends ComponentPropsWithoutRef<\"div\"> {}\n\n/** Top bar component. */\nexport const TopBar = forwardRef<ComponentRef<\"div\">, TopBarProps>(\n function TopBar({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n const { printHidden } = usePrintClassNames();\n const setTopBarHeight = useSetTopBarHeight();\n\n const [topBarEl, setTopBarEl] = useState<HTMLDivElement | null>(null);\n useMeasure(\n topBarEl,\n useCallback(\n (measurement) => setTopBarHeight(measurement?.height),\n [setTopBarHeight],\n ),\n );\n\n const combinedTopBarRef = useCombinedRef(setTopBarEl, forwardedRef);\n return (\n <PortalContext.Provider value={{ container: topBarEl }}>\n <div\n className={cx(prefix(\"top-bar\"), printHidden, className)}\n {...otherProps}\n ref={combinedTopBarRef}\n />\n </PortalContext.Provider>\n );\n },\n);\n","import { cx, Stack } from \"@ostack.tech/ui\";\nimport {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n forwardRef,\n} from \"react\";\n\nimport { usePrefix } from \"../../providers/PrefixSuffixProvider\";\n\n/** Properties of the top bar actions component. */\nexport interface TopBarActionsProps extends ComponentPropsWithoutRef<\n typeof Stack\n> {}\n\n/** Container used to display actions within the top bar. */\nexport const TopBarActions = forwardRef<\n ComponentRef<typeof Stack>,\n TopBarActionsProps\n>(function TopBarActions({ className, ...otherProps }, forwardedRef) {\n const prefix = usePrefix();\n\n return (\n <Stack\n className={cx(prefix(\"top-bar__actions\"), className)}\n direction=\"row\"\n gap={2}\n justifyContent=\"flex-end\"\n {...otherProps}\n ref={forwardedRef}\n />\n );\n});\n","import { faCircleCheck } from \"@fortawesome/free-regular-svg-icons\";\nimport {\n Button,\n type ButtonProps,\n combineEventHandlers,\n useKeyboardShortcut,\n} from \"@ostack.tech/ui\";\nimport { type ReactNode, useDeferredValue } from \"react\";\n\nimport { useLocale } from \"../../providers/LocalizationProvider\";\nimport { useFormIsLoading } from \"../../utils/useFormLoader.tsx\";\nimport {\n useFormIsValidating,\n useFormValidator,\n} from \"../../utils/useFormValidator.ts\";\nimport { useFormAppElement, useFormIsDisabled } from \"../FormApp\";\n\n/** Properties of the validate action. */\nexport interface ValidateActionProps extends Omit<ButtonProps, \"children\"> {\n /** Action's label. */\n label?: ReactNode;\n /**\n * Keybinds for triggering the action. Set to `null` to disable the keyboard\n * shortcut.\n *\n * Keyboard handling is built on top of the\n * [`tinykeys`](https://jamiebuilds.github.io/tinykeys) library. For\n * information on keybinding syntax, read the [`tinykeys`\n * documentation](https://github.com/jamiebuilds/tinykeys).\n *\n * Defaults to the keybinds defined by the current locale.\n */\n keybinds?: string | string[] | null;\n}\n\n/** Action used to validate the form. */\nexport function ValidateAction({\n label,\n keybinds,\n loading,\n enabledWhenLoading,\n disabled,\n onClick,\n ...otherProps\n}: ValidateActionProps) {\n const [locale] = useLocale();\n label ??= locale.ValidateAction.label;\n keybinds ??= locale.ValidateAction.keybinds;\n\n const { validate } = useFormValidator();\n const { validatingAutomatically, validatingManually, validating } =\n useFormIsValidating();\n const deferredValidating = useDeferredValue(validating);\n const formIsDisabled = useFormIsDisabled();\n const formIsLoading = useFormIsLoading();\n const shouldDisable =\n disabled ||\n (loading && !enabledWhenLoading) ||\n formIsDisabled ||\n formIsLoading ||\n validatingManually;\n\n // Set-up keyboard shortcut\n const formAppEl = useFormAppElement();\n useKeyboardShortcut(keybinds, validate, {\n enabled: !shouldDisable,\n target: formAppEl,\n preventDefault: true,\n });\n\n return (\n <Button\n color=\"primary\"\n icon={faCircleCheck}\n vertical\n {...otherProps}\n onClick={combineEventHandlers(validate, onClick as never)}\n disabled={shouldDisable}\n loading={loading || deferredValidating}\n enabledWhenLoading={enabledWhenLoading || validatingAutomatically}\n >\n {label}\n </Button>\n );\n}\n"],"names":["useUiPrefix","defaultPrefixSuffix","activePath","locale","UiLocalizationProvider","focusedPath","controller","FormAppElement","FormApp","mostSpecific","activeAnnex","Annex","state","AnnexTabContent","decode","path","extensions","mimeTypes","description","startIn","id","setPristineOnLoad","validateOnLoad","successMessage","errorMessage","value","Annexes","ControlField","formManager","IssueMessages","info","IssuesPopover","removeAnnex","canBeAdded","AnnexManager","useState","CheckboxControl","key","i","CheckboxGroupControl","formattedValue","arrayValue","min","max","format","fnsFormat","DateControl","DateRangeControl","FileControl","activePage","FormPageHeader","FormPage","FormPages","FormPagesSelect","FormPagesSidebar","FormPagesNavigation","activeStep","FormStepContent","FormStepper","IssueMessage","IssuesPanelMessagesCard","IssuesPanelSummaryCard","NumericControl","stringValue","RadioGroupControl","overwrite","encode","fileName","excludeAcceptAllOption","setPristineOnSave","SelectControl","options","SelectMultipleControl","TableControlCell","TableControlRow","TableControl","schema","initialized","exists","TableControlAddRowTrigger","TableControlRemoveRowTrigger","TableControlContent","TextControl","TopBar","TopBarActions","faCircleCheck"],"mappings":"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"}