@ostack.tech/ui-kform 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +3 -0
  2. package/dist/ostack-ui-kform.cjs +7534 -0
  3. package/dist/ostack-ui-kform.cjs.map +1 -0
  4. package/dist/ostack-ui-kform.css +858 -0
  5. package/dist/ostack-ui-kform.css.map +1 -0
  6. package/dist/ostack-ui-kform.js +7518 -0
  7. package/dist/ostack-ui-kform.js.map +1 -0
  8. package/dist/types/components/Annexes/Annex.d.ts +46 -0
  9. package/dist/types/components/Annexes/AnnexTab.d.ts +5 -0
  10. package/dist/types/components/Annexes/Annexes.d.ts +95 -0
  11. package/dist/types/components/Annexes/AnnexesContext.d.ts +87 -0
  12. package/dist/types/components/Annexes/AnnexesManager.d.ts +47 -0
  13. package/dist/types/components/Annexes/AnnexesMenu.d.ts +10 -0
  14. package/dist/types/components/Annexes/AnnexesTabList.d.ts +8 -0
  15. package/dist/types/components/Annexes/index.d.ts +3 -0
  16. package/dist/types/components/CheckboxControl/CheckboxControl.d.ts +48 -0
  17. package/dist/types/components/CheckboxControl/index.d.ts +1 -0
  18. package/dist/types/components/CheckboxGroupControl/CheckboxGroupControl.d.ts +63 -0
  19. package/dist/types/components/CheckboxGroupControl/index.d.ts +1 -0
  20. package/dist/types/components/ControlField/ControlField.d.ts +50 -0
  21. package/dist/types/components/ControlField/ControlFieldContext.d.ts +33 -0
  22. package/dist/types/components/ControlField/index.d.ts +2 -0
  23. package/dist/types/components/DateControl/DateControl.d.ts +45 -0
  24. package/dist/types/components/DateControl/index.d.ts +1 -0
  25. package/dist/types/components/DateRangeControl/DateRangeControl.d.ts +79 -0
  26. package/dist/types/components/DateRangeControl/index.d.ts +1 -0
  27. package/dist/types/components/FileControl/FileControl.d.ts +68 -0
  28. package/dist/types/components/FileControl/index.d.ts +1 -0
  29. package/dist/types/components/FormApp/FormApp.d.ts +210 -0
  30. package/dist/types/components/FormApp/FormAppContext.d.ts +181 -0
  31. package/dist/types/components/FormApp/FormAppIssueMessages.d.ts +45 -0
  32. package/dist/types/components/FormApp/FormAppStatus.d.ts +23 -0
  33. package/dist/types/components/FormApp/index.d.ts +4 -0
  34. package/dist/types/components/FormPages/FormPage.d.ts +86 -0
  35. package/dist/types/components/FormPages/FormPageHeader.d.ts +7 -0
  36. package/dist/types/components/FormPages/FormPageSidebarItem.d.ts +6 -0
  37. package/dist/types/components/FormPages/FormPages.d.ts +40 -0
  38. package/dist/types/components/FormPages/FormPagesContext.d.ts +67 -0
  39. package/dist/types/components/FormPages/FormPagesNavigation.d.ts +12 -0
  40. package/dist/types/components/FormPages/FormPagesSelect.d.ts +7 -0
  41. package/dist/types/components/FormPages/FormPagesSelectOption.d.ts +6 -0
  42. package/dist/types/components/FormPages/FormPagesSidebar.d.ts +6 -0
  43. package/dist/types/components/FormPages/index.d.ts +3 -0
  44. package/dist/types/components/FormStepper/FormStep.d.ts +8 -0
  45. package/dist/types/components/FormStepper/FormStepContent.d.ts +20 -0
  46. package/dist/types/components/FormStepper/FormStepList.d.ts +7 -0
  47. package/dist/types/components/FormStepper/FormStepper.d.ts +71 -0
  48. package/dist/types/components/FormStepper/FormStepperContext.d.ts +65 -0
  49. package/dist/types/components/FormStepper/index.d.ts +3 -0
  50. package/dist/types/components/IssueAlert/IssueAlert.d.ts +13 -0
  51. package/dist/types/components/IssueAlert/index.d.ts +1 -0
  52. package/dist/types/components/IssueMessage/IssueMessage.d.ts +14 -0
  53. package/dist/types/components/IssueMessage/index.d.ts +1 -0
  54. package/dist/types/components/IssueMessages/IssueMessages.d.ts +70 -0
  55. package/dist/types/components/IssueMessages/index.d.ts +1 -0
  56. package/dist/types/components/IssuesPanel/IssuesPanel.d.ts +106 -0
  57. package/dist/types/components/IssuesPanel/IssuesPanelControls.d.ts +19 -0
  58. package/dist/types/components/IssuesPanel/IssuesPanelMessagesCard.d.ts +13 -0
  59. package/dist/types/components/IssuesPanel/IssuesPanelSummaryCard.d.ts +9 -0
  60. package/dist/types/components/IssuesPanel/index.d.ts +1 -0
  61. package/dist/types/components/IssuesPopover/IssuesPopover.d.ts +15 -0
  62. package/dist/types/components/IssuesPopover/index.d.ts +1 -0
  63. package/dist/types/components/LoadAction/LoadAction.d.ts +22 -0
  64. package/dist/types/components/LoadAction/index.d.ts +1 -0
  65. package/dist/types/components/NumericControl/NumericControl.d.ts +45 -0
  66. package/dist/types/components/NumericControl/index.d.ts +1 -0
  67. package/dist/types/components/PathLink/PathLink.d.ts +16 -0
  68. package/dist/types/components/PathLink/index.d.ts +1 -0
  69. package/dist/types/components/RadioGroupControl/RadioGroupControl.d.ts +56 -0
  70. package/dist/types/components/RadioGroupControl/index.d.ts +1 -0
  71. package/dist/types/components/SaveAction/SaveAction.d.ts +51 -0
  72. package/dist/types/components/SaveAction/index.d.ts +1 -0
  73. package/dist/types/components/SelectControl/SelectControl.d.ts +48 -0
  74. package/dist/types/components/SelectControl/index.d.ts +1 -0
  75. package/dist/types/components/SelectMultipleControl/SelectMultipleControl.d.ts +55 -0
  76. package/dist/types/components/SelectMultipleControl/index.d.ts +1 -0
  77. package/dist/types/components/SubmitAction/SubmitAction.d.ts +94 -0
  78. package/dist/types/components/SubmitAction/index.d.ts +1 -0
  79. package/dist/types/components/TableControl/TableControl.d.ts +64 -0
  80. package/dist/types/components/TableControl/TableControlAddRowTrigger.d.ts +25 -0
  81. package/dist/types/components/TableControl/TableControlApi.d.ts +25 -0
  82. package/dist/types/components/TableControl/TableControlCell.d.ts +7 -0
  83. package/dist/types/components/TableControl/TableControlColumn.d.ts +58 -0
  84. package/dist/types/components/TableControl/TableControlContent.d.ts +7 -0
  85. package/dist/types/components/TableControl/TableControlContext.d.ts +26 -0
  86. package/dist/types/components/TableControl/TableControlPagination.d.ts +2 -0
  87. package/dist/types/components/TableControl/TableControlRemoveRowTrigger.d.ts +61 -0
  88. package/dist/types/components/TableControl/TableControlRow.d.ts +7 -0
  89. package/dist/types/components/TableControl/TableControlRowsPerPage.d.ts +2 -0
  90. package/dist/types/components/TableControl/index.d.ts +8 -0
  91. package/dist/types/components/TextControl/TextControl.d.ts +66 -0
  92. package/dist/types/components/TextControl/index.d.ts +1 -0
  93. package/dist/types/components/TopBar/TopBar.d.ts +6 -0
  94. package/dist/types/components/TopBar/TopBarActions.d.ts +7 -0
  95. package/dist/types/components/TopBar/index.d.ts +2 -0
  96. package/dist/types/components/ValidateAction/ValidateAction.d.ts +21 -0
  97. package/dist/types/components/ValidateAction/index.d.ts +1 -0
  98. package/dist/types/index.d.ts +36 -0
  99. package/dist/types/locale/LocalizationObject.d.ts +34 -0
  100. package/dist/types/locale/defaultLocale.d.ts +3 -0
  101. package/dist/types/locale/en-GB.d.ts +3 -0
  102. package/dist/types/locale/en-US.d.ts +3 -0
  103. package/dist/types/locale/en.d.ts +3 -0
  104. package/dist/types/locale/fr-FR.d.ts +3 -0
  105. package/dist/types/locale/index.d.ts +6 -0
  106. package/dist/types/locale/pt-PT.d.ts +3 -0
  107. package/dist/types/providers/LocalizationProvider/LocalizationContext.d.ts +6 -0
  108. package/dist/types/providers/LocalizationProvider/LocalizationProvider.d.ts +10 -0
  109. package/dist/types/providers/LocalizationProvider/index.d.ts +3 -0
  110. package/dist/types/providers/LocalizationProvider/useLocale.d.ts +3 -0
  111. package/dist/types/providers/PrefixSuffixProvider/PrefixSuffixContext.d.ts +5 -0
  112. package/dist/types/providers/PrefixSuffixProvider/PrefixSuffixProvider.d.ts +9 -0
  113. package/dist/types/providers/PrefixSuffixProvider/index.d.ts +3 -0
  114. package/dist/types/providers/PrefixSuffixProvider/usePrefix.d.ts +6 -0
  115. package/dist/types/utils/dateRestrictions.d.ts +6 -0
  116. package/dist/types/utils/displayStatusConversions.d.ts +6 -0
  117. package/dist/types/utils/mostSpecificPath.d.ts +13 -0
  118. package/dist/types/utils/options.d.ts +18 -0
  119. package/dist/types/utils/pathSpecificity.d.ts +18 -0
  120. package/dist/types/utils/selectionTransformations.d.ts +32 -0
  121. package/dist/types/utils/useControlAutofocus.d.ts +32 -0
  122. package/dist/types/utils/useControlIssues.d.ts +27 -0
  123. package/dist/types/utils/useEqualityFn.d.ts +1 -0
  124. package/dist/types/utils/useFormLoader.d.ts +83 -0
  125. package/dist/types/utils/useFormSaver.d.ts +96 -0
  126. package/dist/types/utils/useFormValidator.d.ts +28 -0
  127. package/dist/types/utils/useRegisterControl.d.ts +24 -0
  128. package/dist/types/utils/useReportValidationFailures.d.ts +5 -0
  129. package/dist/types/utils/useTemporalStringTransformer.d.ts +21 -0
  130. package/package.json +70 -0
  131. package/scss/_utils.scss +6 -0
  132. package/scss/components/Annexes/_Annexes-variables.scss +17 -0
  133. package/scss/components/Annexes/_Annexes.scss +234 -0
  134. package/scss/components/FileControl/_FileControl.scss +52 -0
  135. package/scss/components/FormApp/_FormApp.scss +67 -0
  136. package/scss/components/FormPages/_FormPages-variables.scss +62 -0
  137. package/scss/components/FormPages/_FormPages.scss +288 -0
  138. package/scss/components/IssueMessages/_IssueMessages.scss +13 -0
  139. package/scss/components/IssuesPanel/_IssuesPanel-variables.scss +82 -0
  140. package/scss/components/IssuesPanel/_IssuesPanel.scss +196 -0
  141. package/scss/components/TableControl/_TableControl.scss +21 -0
  142. package/scss/components/TopBar/_TopBar.scss +52 -0
  143. package/scss/index.scss +11 -0
  144. package/scss/scss/_base-variables.scss +5 -0
@@ -0,0 +1,46 @@
1
+ import { type Path } from "@ostack.tech/kform";
2
+ import { ErrorBoundary, TabContent } from "@ostack.tech/ui";
3
+ import * as React from "react";
4
+ import { type IssueMessagesByCode } from "../IssueMessages";
5
+ /** Properties of the annex component. */
6
+ export interface AnnexProps extends Omit<React.ComponentPropsWithoutRef<typeof TabContent>, "value" | "children"> {
7
+ /** Annex path. This should match the path of the annex provided to `Annexes`. */
8
+ path?: string | Path;
9
+ /** Sets the annex as disabled. */
10
+ disabled?: boolean;
11
+ /** Sets the annex as read-only. */
12
+ readOnly?: boolean;
13
+ /**
14
+ * Mapping of issue messages from the path of the field with issues to the
15
+ * issue messages of said field (which are themselves grouped by their code).
16
+ *
17
+ * Provided paths are relative to the annex's path and may contain wildcards,
18
+ * which will have a lower priority when matched against.
19
+ *
20
+ * These messages are used by the `IssueMessages` component.
21
+ *
22
+ * **Note:** Changes to `issueMessages` are handled correctly, but are not
23
+ * efficient. Please make sure that the identity of the provided value doesn't
24
+ * change at every render.
25
+ *
26
+ * Example value:
27
+ *
28
+ * ```tsx
29
+ * {
30
+ * "**": {
31
+ * "valueMissing": "Field is required."
32
+ * },
33
+ * "field": {
34
+ * "valueMissing": "My field cannot be left empty!",
35
+ * "someOtherError": "Text of the other error."
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ issueMessages?: Record<string, IssueMessagesByCode>;
41
+ /** Properties to pass to the `ErrorBoundary` component. */
42
+ errorBoundaryProps?: React.ComponentPropsWithRef<typeof ErrorBoundary>;
43
+ children?: React.ReactNode;
44
+ }
45
+ /** Component containing the content of an annex. */
46
+ export declare const Annex: React.ForwardRefExoticComponent<AnnexProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,5 @@
1
+ import { type AbsolutePath } from "@ostack.tech/kform";
2
+ export interface AnnexTabProps {
3
+ path: AbsolutePath;
4
+ }
5
+ export declare function AnnexTab({ path }: AnnexTabProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,95 @@
1
+ import { type AbsolutePath, type Path } from "@ostack.tech/kform";
2
+ import { Tabs } from "@ostack.tech/ui";
3
+ import * as React from "react";
4
+ /** Properties of the annexes component. */
5
+ export interface AnnexesProps extends Omit<React.ComponentPropsWithoutRef<typeof Tabs>, "defaultValue" | "value" | "onValueChange"> {
6
+ /** Base path for all declared annexes. */
7
+ path?: string | Path;
8
+ /** List of all annexes. */
9
+ annexes: AnnexObject[];
10
+ /** Default active annex. */
11
+ defaultActiveAnnex?: string | Path;
12
+ /** Controlled active annex. */
13
+ activeAnnex?: string | Path;
14
+ /**
15
+ * Function called whenever the active annex changes.
16
+ *
17
+ * @param activeAnnex Path of the new active annex.
18
+ */
19
+ onActiveAnnexChange?: (activeAnnexPath: AbsolutePath | null) => void;
20
+ /**
21
+ * Function called when a new annex is added.
22
+ *
23
+ * @param newAnnexPath Path of the new annex.
24
+ */
25
+ onAnnexAdd?: (newAnnexPath: AbsolutePath) => void;
26
+ /**
27
+ * Function called when an annex is removed.
28
+ *
29
+ * @param removedAnnexPath Path of the removed annex.
30
+ */
31
+ onAnnexRemove?: (removedAnnexPath: AbsolutePath) => void;
32
+ children?: React.ReactNode;
33
+ }
34
+ /** Object representation of an annex. */
35
+ export interface AnnexObject<T = any> {
36
+ /**
37
+ * Annex path. This path may contain a single wildcard (`*`) at the end, when
38
+ * the elements of a collection should be counted as annexes. Otherwise, the
39
+ * path may contain no other wildcards.
40
+ */
41
+ path: string | Path;
42
+ /** Annex's title. */
43
+ title: React.ReactNode | ((value: T) => React.ReactNode);
44
+ /** Annex's subtitle. */
45
+ subtitle?: React.ReactNode | ((value: T, index?: number) => React.ReactNode);
46
+ /** Annex's description. */
47
+ description?: React.ReactNode;
48
+ /**
49
+ * Annex's label in the issues panel. The `title` and `subtitle` are used by
50
+ * default.
51
+ */
52
+ issuesPanelLabel?: React.ReactNode | ((value: T) => React.ReactNode);
53
+ itemTitle?: React.ReactNode | ((value: T, index: number) => React.ReactNode);
54
+ /**
55
+ * Issues panel label for each annex of a collection of annexes. The
56
+ * `subtitle` and index of the item are used by default.
57
+ */
58
+ itemIssuesPanelLabel?: React.ReactNode | ((value: T, index: number) => React.ReactNode);
59
+ /**
60
+ * Title of the annex as a string to display in the document's title.
61
+ *
62
+ * Defaults to the `title` together with the `subtitle` (if it exists) when
63
+ * they are strings.
64
+ *
65
+ * A warning is printed if either the title or the subtitle are defined but
66
+ * aren't strings and `documentTitle` is not provided.
67
+ */
68
+ documentTitle?: string | null | ((value: T, index?: number) => string | null);
69
+ /**
70
+ * Maximum number of annexes matching this path that can be added, when
71
+ * counting collection elements as annexes. By default, if the collection has
72
+ * a `MaxSize` validation, then its value is used.
73
+ */
74
+ maxAnnexes?: number;
75
+ /**
76
+ * Function called when an annex matching this path is being added to choose
77
+ * the value that should be added.
78
+ *
79
+ * The default value being added is provided as an argument and may be edited
80
+ * if required.
81
+ *
82
+ * The value to be added should be returned, or a promise that resolves with
83
+ * said value.
84
+ *
85
+ * To prevent an annex from being added, return `undefined`/`null` (or a
86
+ * promise which resolves with `undefined`/`null`).
87
+ *
88
+ * @param value - Value being added, can be edited.
89
+ * @returns Value to be added, `undefined`/`null` if the annex shouldn't be
90
+ * added (or a promise that resolves with said values).
91
+ */
92
+ getValue?: (value: T) => T | null | undefined | Promise<T | null | undefined>;
93
+ }
94
+ /** Root component used to render form annexes. */
95
+ export declare const Annexes: React.ForwardRefExoticComponent<AnnexesProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,87 @@
1
+ import { AbsolutePath, type DisplayStatus, type FormManager, type Path, type Schema, type SealedValidationIssue, type TableRowId } from "@ostack.tech/kform";
2
+ import * as React from "react";
3
+ import { type AnnexesProps, type AnnexObject } from "./Annexes.tsx";
4
+ /** Value of the annexes' context. */
5
+ export type AnnexesContextValue = AnnexesStore;
6
+ /** Resolved annex object. */
7
+ export interface ResolvedAnnexObject extends AnnexObject {
8
+ path: AbsolutePath;
9
+ }
10
+ /** Annex state. */
11
+ export interface AnnexState {
12
+ path: AbsolutePath;
13
+ title: React.ReactNode;
14
+ subtitle?: React.ReactNode;
15
+ description?: React.ReactNode;
16
+ documentTitle?: string | null;
17
+ isRepetitive: boolean;
18
+ schema: Schema;
19
+ isNull: boolean;
20
+ dirty: boolean | undefined;
21
+ deferredDisplayStatus: DisplayStatus | undefined;
22
+ deferredIssuesToDisplay: SealedValidationIssue[];
23
+ }
24
+ /** Repetitive annex state. */
25
+ export type RepetitiveAnnexState = Pick<ResolvedAnnexObject, "path" | "maxAnnexes"> & {
26
+ rowIds?: TableRowId[];
27
+ schema: Schema;
28
+ deferredIssuesToDisplay: SealedValidationIssue[];
29
+ };
30
+ /** State of the annexes. */
31
+ export interface AnnexesState {
32
+ annexes: ResolvedAnnexObject[];
33
+ activeAnnex: AbsolutePath | null;
34
+ nextActiveAnnex: AbsolutePath | null;
35
+ activeAnnexIndex: () => number;
36
+ annexStates: [Record<string, AnnexState | null>];
37
+ repetitiveAnnexStates: [Record<string, RepetitiveAnnexState | null>];
38
+ tabStates: () => AnnexState[];
39
+ tablessStates: () => (AnnexState | RepetitiveAnnexState)[];
40
+ waitingRegistration: () => AbsolutePath[];
41
+ actions: AnnexesActions;
42
+ }
43
+ /** Actions of the annexes. */
44
+ export interface AnnexesActions {
45
+ getAnnexState: (path: AbsolutePath) => AnnexState | null;
46
+ getRepetitiveAnnexState: (path: AbsolutePath) => RepetitiveAnnexState | null;
47
+ setAnnexes: (annexes: ResolvedAnnexObject[]) => void;
48
+ buildAnnexStates: (annexes?: ResolvedAnnexObject[]) => Record<string, AnnexState | null>;
49
+ buildRepetitiveAnnexStates: (annexes?: ResolvedAnnexObject[]) => Record<string, RepetitiveAnnexState | null>;
50
+ setActiveAnnex: (activeAnnex: string | Path | null) => void;
51
+ updateActiveAnnex: (oldActiveAnnexIndex: number) => void;
52
+ registerAnnexState: (path: AbsolutePath, state: AnnexState) => void;
53
+ registerRepetitiveAnnexState: (path: AbsolutePath, state: RepetitiveAnnexState) => void;
54
+ addAnnex: (path: AbsolutePath, toAdd: unknown) => Promise<void>;
55
+ removeAnnex: (path: AbsolutePath, isRepetitive: boolean) => Promise<void>;
56
+ }
57
+ /** Annexes' store. */
58
+ export type AnnexesStore = ReturnType<typeof useCreateAnnexesContext>;
59
+ /** Annexes' context. */
60
+ export declare const AnnexesContext: React.Context<(Omit<import("zustand").StoreApi<AnnexesState>, "subscribe"> & {
61
+ subscribe: {
62
+ (listener: (selectedState: AnnexesState, previousSelectedState: AnnexesState) => void): () => void;
63
+ <U>(selector: (state: AnnexesState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
64
+ equalityFn?: ((a: U, b: U) => boolean) | undefined;
65
+ fireImmediately?: boolean;
66
+ } | undefined): () => void;
67
+ };
68
+ }) | null>;
69
+ /** Options used to create the annexes' context. */
70
+ export interface UseCreateAnnexesContextOptions extends Pick<AnnexesProps, "defaultActiveAnnex" | "activeAnnex" | "onActiveAnnexChange" | "onAnnexAdd" | "onAnnexRemove"> {
71
+ formManager: FormManager;
72
+ basePath: AbsolutePath;
73
+ resolvedAnnexes: ResolvedAnnexObject[];
74
+ }
75
+ /** Hook used to create the annexes' context. */
76
+ export declare function useCreateAnnexesContext({ formManager, basePath, resolvedAnnexes, defaultActiveAnnex, activeAnnex, onActiveAnnexChange, onAnnexAdd, onAnnexRemove, }: UseCreateAnnexesContextOptions): Omit<import("zustand").StoreApi<AnnexesState>, "subscribe"> & {
77
+ subscribe: {
78
+ (listener: (selectedState: AnnexesState, previousSelectedState: AnnexesState) => void): () => void;
79
+ <U>(selector: (state: AnnexesState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
80
+ equalityFn?: ((a: U, b: U) => boolean) | undefined;
81
+ fireImmediately?: boolean;
82
+ } | undefined): () => void;
83
+ };
84
+ };
85
+ /** Returns the annexes' context. */
86
+ export declare function useAnnexesContext(): AnnexesContextValue;
87
+ export declare function useAnnexState<T>(path: AbsolutePath, selector: (state: AnnexState | null) => T): T;
@@ -0,0 +1,47 @@
1
+ import { type Button, type DropdownMenu, type DropdownMenuContent, type TabList } from "@ostack.tech/ui";
2
+ import * as React from "react";
3
+ /** Properties of the annexes' manager component. */
4
+ export interface AnnexesManagerProps extends React.ComponentPropsWithoutRef<"nav"> {
5
+ /** Text of the menu button. */
6
+ menuButtonText?: React.ReactNode;
7
+ /** Text of the "add annex" item. */
8
+ addAnnexText?: React.ReactNode;
9
+ /** Label of the remove annex button, announced by assistive technologies. */
10
+ removeAnnexButtonLabel?: string;
11
+ /**
12
+ * Hint on how to remove an annex via keyboard, announced by assistive
13
+ * technologies.
14
+ */
15
+ removeAnnexKeyboardHint?: string;
16
+ /** Title of the "remove annex" confirm dialog. */
17
+ removeAnnexConfirmDialogTitle?: React.ReactNode;
18
+ /**
19
+ * Function that should return the message of the "remove annex" confirm
20
+ * dialog, given a node with the name of the annex.
21
+ *
22
+ * @param annexName Node containing the name of the annex.
23
+ */
24
+ removeAnnexConfirmDialogMessage?: (annexName: React.ReactNode) => React.ReactNode;
25
+ /** Text of the "remove annex" confirm dialog OK button. */
26
+ removeAnnexConfirmDialogOkText?: React.ReactNode;
27
+ /** Text of the "remove annex" confirm dialog cancel button. */
28
+ removeAnnexConfirmDialogCancelText?: React.ReactNode;
29
+ /** Properties to pass to the menu container element. */
30
+ menuContainerProps?: React.ComponentPropsWithRef<"div">;
31
+ /** Properties to pass to the menu trigger component. */
32
+ menuTriggerProps?: Omit<React.ComponentPropsWithRef<typeof Button>, "icon">;
33
+ /** Properties to pass to the menu content component. */
34
+ menuContentProps?: React.ComponentPropsWithRef<typeof DropdownMenuContent>;
35
+ /** Properties to pass to the menu component. */
36
+ menuProps?: React.ComponentPropsWithRef<typeof DropdownMenu>;
37
+ /** Properties to pass to the tab-list container element. */
38
+ tabListContainerProps?: React.ComponentPropsWithRef<"div">;
39
+ /** Properties to pass to the tab-list component. */
40
+ tabListProps?: React.ComponentPropsWithRef<typeof TabList>;
41
+ }
42
+ /**
43
+ * Component used to manage the form's annexes. Provides a menu that allows
44
+ * changing, adding, and removing annexes, as well as a list of tabs for each
45
+ * existing annex.
46
+ */
47
+ export declare const AnnexesManager: React.ForwardRefExoticComponent<AnnexesManagerProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,10 @@
1
+ import { Button, DropdownMenu, DropdownMenuContent } from "@ostack.tech/ui";
2
+ import * as React from "react";
3
+ import { type AnnexesManager } from "./AnnexesManager.tsx";
4
+ /** Properties of the annexes' menu. */
5
+ export interface AnnexesMenuProps extends Pick<React.ComponentPropsWithoutRef<typeof AnnexesManager>, "menuButtonText" | "addAnnexText" | "removeAnnexButtonLabel" | "removeAnnexKeyboardHint" | "removeAnnexConfirmDialogTitle" | "removeAnnexConfirmDialogMessage" | "removeAnnexConfirmDialogOkText" | "removeAnnexConfirmDialogCancelText">, React.ComponentPropsWithoutRef<typeof DropdownMenu> {
6
+ menuTriggerProps?: Omit<React.ComponentPropsWithRef<typeof Button>, "icon">;
7
+ menuContentProps?: React.ComponentPropsWithRef<typeof DropdownMenuContent>;
8
+ }
9
+ /** Component that allows to navigate between, add, and remove annexes. */
10
+ export declare function AnnexesMenu({ menuButtonText, addAnnexText, removeAnnexButtonLabel, removeAnnexKeyboardHint, removeAnnexConfirmDialogTitle, removeAnnexConfirmDialogMessage, removeAnnexConfirmDialogOkText, removeAnnexConfirmDialogCancelText, defaultOpen, open: controlledOpen, onOpenChange, menuTriggerProps, menuContentProps, ...otherProps }: AnnexesMenuProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { TabList } from "@ostack.tech/ui";
2
+ import * as React from "react";
3
+ /** Properties of the annex tab list component. */
4
+ export interface AnnexTabListProps extends React.ComponentPropsWithoutRef<typeof TabList> {
5
+ hideNonActiveOnSmallScreens: boolean;
6
+ }
7
+ /** List of annex tabs. */
8
+ export declare const AnnexesTabList: React.ForwardRefExoticComponent<AnnexTabListProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,3 @@
1
+ export * from "./Annex.tsx";
2
+ export * from "./Annexes.tsx";
3
+ export * from "./AnnexesManager.tsx";
@@ -0,0 +1,48 @@
1
+ import { type Path } from "@ostack.tech/kform";
2
+ import { type InputController, type InputOptions } from "@ostack.tech/kform-react";
3
+ import { Checkbox, type CheckboxChecked } from "@ostack.tech/ui";
4
+ import * as React from "react";
5
+ import { type IssueMessages, type IssueMessagesByCode } from "../IssueMessages";
6
+ /** Properties of the checkbox control component. */
7
+ export interface CheckboxControlProps<T extends boolean | null = boolean | null> extends Omit<InputOptions<T, CheckboxChecked, React.ComponentRef<typeof Checkbox>>, "enabled" | "format" | "parse">, Omit<React.ComponentPropsWithoutRef<typeof Checkbox>, "defaultChecked" | "checked" | "status"> {
8
+ /** Path to the value. */
9
+ path?: string | Path;
10
+ /**
11
+ * Issue messages of this control.
12
+ *
13
+ * Mapping from an issue's code to its message.
14
+ */
15
+ issueMessages?: IssueMessagesByCode;
16
+ /**
17
+ * Label to use in the issues panel when displaying issues associated with
18
+ * this field.
19
+ *
20
+ * This label has priority over the field's `ControlLabel`.
21
+ */
22
+ issuesPanelLabel?: React.ReactNode;
23
+ /**
24
+ * Whether to display the issues associated with this control.
25
+ *
26
+ * @default true
27
+ */
28
+ displayIssues?: boolean;
29
+ /**
30
+ * Whether to prevent the auto-focusing behaviour that causes this control to
31
+ * be focused when the form app's `focus` is called with this control's path.
32
+ *
33
+ * Preventing this behaviour is useful when multiple controls for the same
34
+ * path are rendered at once, and only one of them should be focused.
35
+ *
36
+ * @default false
37
+ */
38
+ preventAutoFocus?: boolean;
39
+ /** Reference to the control's API. */
40
+ apiRef?: React.Ref<InputController<T, CheckboxChecked, React.ComponentRef<typeof Checkbox>> | undefined>;
41
+ /** Properties to pass to the `IssueMessages` component. */
42
+ issueMessagesProps?: Omit<React.ComponentPropsWithRef<typeof IssueMessages>, "path" | "issues" | "messages" | "unwrapped">;
43
+ }
44
+ /**
45
+ * Checkbox control component supporting (possibly nullable) schemas of type
46
+ * "Boolean". `null` values are represented as an "indeterminate" checkbox.
47
+ */
48
+ export declare const CheckboxControl: React.ForwardRefExoticComponent<CheckboxControlProps<boolean | null> & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ export * from "./CheckboxControl.tsx";
@@ -0,0 +1,63 @@
1
+ import { type Path } from "@ostack.tech/kform";
2
+ import { type Listable, type ListableInputController, type ListableInputOptions } from "@ostack.tech/kform-react";
3
+ import { Checkbox, CheckboxGroup } from "@ostack.tech/ui";
4
+ import * as React from "react";
5
+ import { type IssueMessages, type IssueMessagesByCode } from "../IssueMessages";
6
+ /** Checkbox in object notation. */
7
+ export type CheckboxObject<T = unknown> = Omit<React.ComponentPropsWithRef<typeof Checkbox>, "defaultChecked" | "checked" | "value" | "children"> & {
8
+ /** Option value. */
9
+ value: T;
10
+ /** Option's rendered text. */
11
+ text?: React.ReactNode;
12
+ /** Option's unique key. */
13
+ key?: React.Key;
14
+ };
15
+ /** Properties of the checkbox group control component. */
16
+ export interface CheckboxGroupControlProps<T = unknown, TListable extends Listable<T> | null = Listable<T> | null> extends Omit<ListableInputOptions<T, TListable, string[], React.ComponentRef<typeof CheckboxGroup>>, "enabled" | "formatFromArray" | "parseToArray">, Omit<React.ComponentPropsWithoutRef<typeof CheckboxGroup>, "defaultValue" | "value" | "onValueChange" | "children" | "status"> {
17
+ /** Path to the value. */
18
+ path?: string | Path;
19
+ /** Checkbox group control options. */
20
+ options: CheckboxObject<T>[];
21
+ /**
22
+ * Issue messages of this control.
23
+ *
24
+ * Mapping from an issue's code to its message.
25
+ */
26
+ issueMessages?: IssueMessagesByCode;
27
+ /**
28
+ * Label to use in the issues panel when displaying issues associated with
29
+ * this field.
30
+ *
31
+ * This label has priority over the field's `ControlLabel`.
32
+ */
33
+ issuesPanelLabel?: React.ReactNode;
34
+ /**
35
+ * Whether to display the issues associated with this control.
36
+ *
37
+ * @default true
38
+ */
39
+ displayIssues?: boolean;
40
+ /**
41
+ * Whether to prevent the auto-focusing behaviour that causes this control to
42
+ * be focused when the form app's `focus` is called with this control's path.
43
+ *
44
+ * Preventing this behaviour is useful when multiple controls for the same
45
+ * path are rendered at once, and only one of them should be focused.
46
+ *
47
+ * @default false
48
+ */
49
+ preventAutoFocus?: boolean;
50
+ /** Reference to the control's API. */
51
+ apiRef?: React.Ref<ListableInputController<T, TListable, string[], React.ComponentRef<typeof CheckboxGroup>> | undefined>;
52
+ /** Properties to pass to the `IssueMessages` component. */
53
+ issueMessagesProps?: Omit<React.ComponentPropsWithRef<typeof IssueMessages>, "path" | "issues" | "messages" | "unwrapped">;
54
+ }
55
+ /**
56
+ * Checkbox group control component supporting (possibly nullable) listable
57
+ * schemas with elements of any type.
58
+ *
59
+ * If the schema is nullable, this component sets the form value to `null` when
60
+ * the control contains no elements. Note, however, that the form may still hold
61
+ * an empty listable as value if set programmatically.
62
+ */
63
+ export declare const CheckboxGroupControl: React.ForwardRefExoticComponent<CheckboxGroupControlProps<unknown, Listable<unknown> | null> & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ export * from "./CheckboxGroupControl.tsx";
@@ -0,0 +1,50 @@
1
+ import { Path } from "@ostack.tech/kform";
2
+ import { Field } from "@ostack.tech/ui";
3
+ import * as React from "react";
4
+ /** Properties of the control field component. */
5
+ export interface ControlFieldProps extends React.ComponentPropsWithoutRef<typeof Field> {
6
+ /** Path of the field; inner control paths will be relative to this path. */
7
+ path?: string | Path;
8
+ /**
9
+ * Whether to show the control field.
10
+ *
11
+ * The component will, by default, automatically reset its inner controls when
12
+ * the control field becomes hidden.
13
+ *
14
+ * @default true
15
+ */
16
+ shown?: boolean;
17
+ /**
18
+ * Whether to reset the inner controls when the control field becomes hidden.
19
+ *
20
+ * @default true
21
+ */
22
+ resetOnHide?: boolean;
23
+ /**
24
+ * Whether to set inner controls as untouched when the control field becomes
25
+ * hidden.
26
+ *
27
+ * @default resetOnHide
28
+ */
29
+ setUntouchedOnHide?: boolean;
30
+ /**
31
+ * Whether to set inner controls as pristine when the control field becomes
32
+ * hidden.
33
+ *
34
+ * @default resetOnHide
35
+ */
36
+ setPristineOnHide?: boolean;
37
+ }
38
+ /**
39
+ * Component used to group controls with a label, helper text, and/or feedback.
40
+ *
41
+ * The component can be conditionally shown via the `shown` property which, by
42
+ * default, when changing from `true` to `false` will reset its inner controls.
43
+ *
44
+ * Added labels automatically "point" to the control and are set to "required"
45
+ * when requested by the control.
46
+ *
47
+ * Aria descriptions and error messages are set on the control based on the
48
+ * provided helper texts or feedbacks.
49
+ */
50
+ export declare const ControlField: React.ForwardRefExoticComponent<ControlFieldProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,33 @@
1
+ import { type AbsolutePath, type FormManager, type Schema, type SealedValidationIssue } from "@ostack.tech/kform";
2
+ import { type Controller } from "@ostack.tech/kform-react";
3
+ import * as React from "react";
4
+ /** Value of the control field context. */
5
+ export type ControlFieldContextValue = ControlFieldStore;
6
+ /** State of the control field. */
7
+ export interface ControlFieldState {
8
+ controlStates: Record<string, ControlState>;
9
+ }
10
+ /** State of a control accessible to the whole field. */
11
+ export interface ControlState {
12
+ formManager: FormManager;
13
+ schema: Schema;
14
+ path: AbsolutePath;
15
+ exists: boolean;
16
+ deferredIssuesToDisplay: SealedValidationIssue[];
17
+ }
18
+ /** Control field store. */
19
+ export type ControlFieldStore = ReturnType<typeof useCreateControlFieldContext>;
20
+ /** Control field context. */
21
+ export declare const ControlFieldContext: React.Context<import("zustand").StoreApi<ControlFieldState> | null>;
22
+ /** Hook which creates the control field context value. */
23
+ export declare function useCreateControlFieldContext(): import("zustand").StoreApi<ControlFieldState>;
24
+ /** Hook that returns access to the control field's store. */
25
+ export declare function useControlFieldStore<T>(selector: (state: Partial<ControlFieldState>) => T): T;
26
+ /** Hook exposing whether a component is being rendered within a control field. */
27
+ export declare function useIsInControlField(): boolean;
28
+ /**
29
+ * Hook that makes a control field aware of a controller.
30
+ *
31
+ * The passed `controller` object should not be different on every render.
32
+ */
33
+ export declare function useRegisterControllerWithinControlField<T = unknown>(controller: Controller<T>, deferredIssuesToDisplay: SealedValidationIssue[]): void;
@@ -0,0 +1,2 @@
1
+ export * from "./ControlField.tsx";
2
+ export { useIsInControlField, useRegisterControllerWithinControlField, } from "./ControlFieldContext.ts";
@@ -0,0 +1,45 @@
1
+ import { type Path } from "@ostack.tech/kform";
2
+ import { type Temporal, type TemporalInputController, type TemporalInputOptions } from "@ostack.tech/kform-react";
3
+ import { DateInput } from "@ostack.tech/ui";
4
+ import * as React from "react";
5
+ import { type IssueMessages, type IssueMessagesByCode } from "../IssueMessages";
6
+ /** Properties of the date control component. */
7
+ export interface DateControlProps<T extends Temporal | null = Temporal | null> extends Omit<TemporalInputOptions<T, string, React.ComponentRef<typeof DateInput>>, "enabled" | "formatFromString" | "parseToString">, Omit<React.ComponentPropsWithoutRef<typeof DateInput>, "defaultValue" | "value" | "onValueChange" | "status"> {
8
+ /** Path to the value. */
9
+ path?: string | Path;
10
+ /**
11
+ * Issue messages of this control.
12
+ *
13
+ * Mapping from an issue's code to its message.
14
+ */
15
+ issueMessages?: IssueMessagesByCode;
16
+ /**
17
+ * Label to use in the issues panel when displaying issues associated with
18
+ * this field.
19
+ *
20
+ * This label has priority over the field's `ControlLabel`.
21
+ */
22
+ issuesPanelLabel?: React.ReactNode;
23
+ /**
24
+ * Whether to display the issues associated with this control.
25
+ *
26
+ * @default true
27
+ */
28
+ displayIssues?: boolean;
29
+ /**
30
+ * Whether to prevent the auto-focusing behaviour that causes this control to
31
+ * be focused when the form app's `focus` is called with this control's path.
32
+ *
33
+ * Preventing this behaviour is useful when multiple controls for the same
34
+ * path are rendered at once, and only one of them should be focused.
35
+ *
36
+ * @default false
37
+ */
38
+ preventAutoFocus?: boolean;
39
+ /** Reference to the control's API. */
40
+ apiRef?: React.Ref<TemporalInputController<T, string, React.ComponentRef<typeof DateInput>> | undefined>;
41
+ /** Properties to pass to the `IssueMessages` component. */
42
+ issueMessagesProps?: Omit<React.ComponentPropsWithRef<typeof IssueMessages>, "path" | "issues" | "messages" | "unwrapped">;
43
+ }
44
+ /** Date control component supporting nullable temporal schemas. */
45
+ export declare const DateControl: React.ForwardRefExoticComponent<DateControlProps<Temporal | null> & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1 @@
1
+ export * from "./DateControl.tsx";
@@ -0,0 +1,79 @@
1
+ import { type Path } from "@ostack.tech/kform";
2
+ import { type Temporal, type TemporalInputController, type TemporalInputOptions } from "@ostack.tech/kform-react";
3
+ import { DateRangeInput } from "@ostack.tech/ui";
4
+ import * as React from "react";
5
+ import { type IssueMessages, type IssueMessagesByCode } from "../IssueMessages";
6
+ /** Properties of the date-range control component. */
7
+ export interface DateRangeControlProps<TStart extends Temporal | null = Temporal | null, TEnd extends Temporal | null = TStart> extends Omit<React.ComponentPropsWithoutRef<typeof DateRangeInput>, "defaultValue" | "value"> {
8
+ /** Path to the start value. */
9
+ startPath: string | Path;
10
+ /** Path to the end value. */
11
+ endPath: string | Path;
12
+ /**
13
+ * Issue messages of this control's start.
14
+ *
15
+ * Mapping from an issue's code to its message.
16
+ */
17
+ startIssueMessages?: IssueMessagesByCode;
18
+ /**
19
+ * Issue messages of this control's end.
20
+ *
21
+ * Mapping from an issue's code to its message.
22
+ */
23
+ endIssueMessages?: IssueMessagesByCode;
24
+ /**
25
+ * Label to use in the issues panel when displaying issues associated with
26
+ * this field.
27
+ *
28
+ * This label has priority over the field's `ControlLabel`.
29
+ */
30
+ issuesPanelLabel?: React.ReactNode;
31
+ /**
32
+ * Label suffix to use in the issues panel when displaying issues associated
33
+ * with this field's start date.
34
+ */
35
+ issuesPanelStartLabelSuffix?: React.ReactNode;
36
+ /**
37
+ * Label suffix to use in the issues panel when displaying issues associated
38
+ * with this field's end date.
39
+ */
40
+ issuesPanelEndLabelSuffix?: React.ReactNode;
41
+ /**
42
+ * Whether to display the issues associated with this control.
43
+ *
44
+ * @default true
45
+ */
46
+ displayIssues?: boolean;
47
+ /**
48
+ * Whether to prevent the auto-focusing behaviour that causes this control to
49
+ * be focused when the form app's `focus` is called with this control's path.
50
+ *
51
+ * Preventing this behaviour is useful when multiple controls for the same
52
+ * path are rendered at once, and only one of them should be focused.
53
+ *
54
+ * @default false
55
+ */
56
+ preventAutoFocus?: boolean;
57
+ /** Reference to the start control's API. */
58
+ startApiRef?: React.Ref<TemporalInputController<TStart, string> | undefined>;
59
+ /** Reference to the end control's API. */
60
+ endApiRef?: React.Ref<TemporalInputController<TEnd, string> | undefined>;
61
+ /** Properties to pass to the `IssueMessages` component. */
62
+ issueMessagesProps?: Omit<React.ComponentPropsWithRef<typeof IssueMessages>, "path" | "issues" | "messages" | "unwrapped">;
63
+ onStartInitialized?: TemporalInputOptions<TStart, string>["onInitialized"];
64
+ onStartFormManagerEvent?: TemporalInputOptions<TStart, string>["onFormManagerEvent"];
65
+ onStartValueChange?: TemporalInputOptions<TStart, string>["onValueChange"];
66
+ onStartValidationStatusChange?: TemporalInputOptions<TStart, string>["onValidationStatusChange"];
67
+ onStartDisplayStatusChange?: TemporalInputOptions<TStart, string>["onDisplayStatusChange"];
68
+ onStartDirtyStatusChange?: TemporalInputOptions<TStart, string>["onDirtyStatusChange"];
69
+ onStartTouchedStatusChange?: TemporalInputOptions<TStart, string>["onTouchedStatusChange"];
70
+ onEndInitialized?: TemporalInputOptions<TEnd, string>["onInitialized"];
71
+ onEndFormManagerEvent?: TemporalInputOptions<TEnd, string>["onFormManagerEvent"];
72
+ onEndValueChange?: TemporalInputOptions<TEnd, string>["onValueChange"];
73
+ onEndValidationStatusChange?: TemporalInputOptions<TEnd, string>["onValidationStatusChange"];
74
+ onEndDisplayStatusChange?: TemporalInputOptions<TEnd, string>["onDisplayStatusChange"];
75
+ onEndDirtyStatusChange?: TemporalInputOptions<TEnd, string>["onDirtyStatusChange"];
76
+ onEndTouchedStatusChange?: TemporalInputOptions<TEnd, string>["onTouchedStatusChange"];
77
+ }
78
+ /** Date-range control component supporting nullable temporal schemas. */
79
+ export declare const DateRangeControl: React.ForwardRefExoticComponent<DateRangeControlProps<Temporal | null, Temporal | null> & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ export * from "./DateRangeControl.tsx";