@osdk/react-components 0.10.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c → 0.10.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 (113) hide show
  1. package/AGENTS.md +6 -6
  2. package/CHANGELOG.md +8 -7
  3. package/README.md +4 -4
  4. package/build/browser/action-form/ActionForm.js +7 -3
  5. package/build/browser/action-form/ActionForm.js.map +1 -1
  6. package/build/browser/action-form/ActionFormApi.js.map +1 -1
  7. package/build/browser/action-form/BaseForm.js +58 -15
  8. package/build/browser/action-form/BaseForm.js.map +1 -1
  9. package/build/browser/action-form/FormSection.js +92 -0
  10. package/build/browser/action-form/FormSection.js.map +1 -0
  11. package/build/browser/action-form/FormSection.module.css +144 -0
  12. package/build/browser/action-form/FormSection.module.css.js +20 -0
  13. package/build/browser/action-form/fields/ObjectSelectField.js +1 -2
  14. package/build/browser/action-form/fields/ObjectSelectField.js.map +1 -1
  15. package/build/browser/action-form/fields/ObjectSetField.js +1 -2
  16. package/build/browser/action-form/fields/ObjectSetField.js.map +1 -1
  17. package/build/browser/filter-list/hooks/usePropertyAggregation.js +1 -1
  18. package/build/browser/filter-list/hooks/usePropertyAggregation.js.map +1 -1
  19. package/build/browser/filter-list/inputs/DateRangeFilterInput.js +1 -1
  20. package/build/browser/filter-list/inputs/DateRangeFilterInput.js.map +1 -1
  21. package/build/browser/filter-list/inputs/LinkedPropertyInput.js +1 -1
  22. package/build/browser/filter-list/inputs/LinkedPropertyInput.js.map +1 -1
  23. package/build/browser/filter-list/inputs/NumberRangeFilterInput.js +1 -1
  24. package/build/browser/filter-list/inputs/NumberRangeFilterInput.js.map +1 -1
  25. package/build/browser/object-table/ObjectTableApi.js.map +1 -1
  26. package/build/browser/object-table/hooks/useFunctionColumnsData.js +2 -2
  27. package/build/browser/object-table/hooks/useFunctionColumnsData.js.map +1 -1
  28. package/build/browser/object-table/hooks/useObjectTableData.js +1 -1
  29. package/build/browser/object-table/hooks/useObjectTableData.js.map +1 -1
  30. package/build/browser/public/experimental/action-form.js.map +1 -1
  31. package/build/browser/styles.css +205 -0
  32. package/build/browser/tokens/component-tokens/form-section.css +58 -0
  33. package/build/browser/tokens.css +1 -0
  34. package/build/browser/util/UserAgent.js +1 -1
  35. package/build/browser/util/UserAgent.js.map +1 -1
  36. package/build/browser/util/withOsdkMetrics.js +1 -1
  37. package/build/browser/util/withOsdkMetrics.js.map +1 -1
  38. package/build/cjs/{chunk-YUN7IILR.cjs → chunk-5DE6S6TS.cjs} +5 -5
  39. package/build/cjs/chunk-5DE6S6TS.cjs.map +1 -0
  40. package/build/cjs/{chunk-FVA2OU7H.cjs → chunk-NFFWKDF6.cjs} +12 -13
  41. package/build/cjs/chunk-NFFWKDF6.cjs.map +1 -0
  42. package/build/cjs/{chunk-RVARLNVS.cjs → chunk-PHMG5MOF.cjs} +4 -4
  43. package/build/cjs/{chunk-RVARLNVS.cjs.map → chunk-PHMG5MOF.cjs.map} +1 -1
  44. package/build/cjs/{chunk-HV6Q2FFI.cjs → chunk-QQXIHLYS.cjs} +8 -9
  45. package/build/cjs/chunk-QQXIHLYS.cjs.map +1 -0
  46. package/build/cjs/{chunk-4OIHG235.cjs → chunk-Y6KKCW7D.cjs} +336 -220
  47. package/build/cjs/chunk-Y6KKCW7D.cjs.map +1 -0
  48. package/build/cjs/public/experimental/action-form.cjs +4 -4
  49. package/build/cjs/public/experimental/action-form.css +102 -0
  50. package/build/cjs/public/experimental/action-form.css.map +1 -1
  51. package/build/cjs/public/experimental/action-form.d.cts +35 -2
  52. package/build/cjs/public/experimental/filter-list.cjs +6 -6
  53. package/build/cjs/public/experimental/object-table.cjs +8 -8
  54. package/build/cjs/public/experimental/object-table.d.cts +1 -1
  55. package/build/cjs/public/experimental/pdf-viewer.cjs +24 -24
  56. package/build/cjs/public/experimental.cjs +39 -39
  57. package/build/cjs/public/experimental.css +102 -0
  58. package/build/cjs/public/experimental.css.map +1 -1
  59. package/build/cjs/public/experimental.d.cts +2 -2
  60. package/build/esm/action-form/ActionForm.js +7 -3
  61. package/build/esm/action-form/ActionForm.js.map +1 -1
  62. package/build/esm/action-form/ActionFormApi.js.map +1 -1
  63. package/build/esm/action-form/BaseForm.js +58 -15
  64. package/build/esm/action-form/BaseForm.js.map +1 -1
  65. package/build/esm/action-form/FormSection.js +92 -0
  66. package/build/esm/action-form/FormSection.js.map +1 -0
  67. package/build/esm/action-form/FormSection.module.css +144 -0
  68. package/build/esm/action-form/fields/ObjectSelectField.js +1 -2
  69. package/build/esm/action-form/fields/ObjectSelectField.js.map +1 -1
  70. package/build/esm/action-form/fields/ObjectSetField.js +1 -2
  71. package/build/esm/action-form/fields/ObjectSetField.js.map +1 -1
  72. package/build/esm/filter-list/hooks/usePropertyAggregation.js +1 -1
  73. package/build/esm/filter-list/hooks/usePropertyAggregation.js.map +1 -1
  74. package/build/esm/filter-list/inputs/DateRangeFilterInput.js +1 -1
  75. package/build/esm/filter-list/inputs/DateRangeFilterInput.js.map +1 -1
  76. package/build/esm/filter-list/inputs/LinkedPropertyInput.js +1 -1
  77. package/build/esm/filter-list/inputs/LinkedPropertyInput.js.map +1 -1
  78. package/build/esm/filter-list/inputs/NumberRangeFilterInput.js +1 -1
  79. package/build/esm/filter-list/inputs/NumberRangeFilterInput.js.map +1 -1
  80. package/build/esm/object-table/ObjectTableApi.js.map +1 -1
  81. package/build/esm/object-table/hooks/useFunctionColumnsData.js +2 -2
  82. package/build/esm/object-table/hooks/useFunctionColumnsData.js.map +1 -1
  83. package/build/esm/object-table/hooks/useObjectTableData.js +1 -1
  84. package/build/esm/object-table/hooks/useObjectTableData.js.map +1 -1
  85. package/build/esm/public/experimental/action-form.js.map +1 -1
  86. package/build/esm/tokens/component-tokens/form-section.css +58 -0
  87. package/build/esm/tokens.css +1 -0
  88. package/build/esm/util/UserAgent.js +1 -1
  89. package/build/esm/util/UserAgent.js.map +1 -1
  90. package/build/esm/util/withOsdkMetrics.js +1 -1
  91. package/build/esm/util/withOsdkMetrics.js.map +1 -1
  92. package/build/types/action-form/ActionForm.d.ts.map +1 -1
  93. package/build/types/action-form/ActionFormApi.d.ts +34 -1
  94. package/build/types/action-form/ActionFormApi.d.ts.map +1 -1
  95. package/build/types/action-form/BaseForm.d.ts.map +1 -1
  96. package/build/types/action-form/FormSection.d.ts +8 -0
  97. package/build/types/action-form/FormSection.d.ts.map +1 -0
  98. package/build/types/action-form/fields/ObjectSelectField.d.ts.map +1 -1
  99. package/build/types/action-form/fields/ObjectSetField.d.ts.map +1 -1
  100. package/build/types/object-table/ObjectTableApi.d.ts +1 -1
  101. package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
  102. package/build/types/object-table/hooks/useObjectTableData.d.ts +1 -1
  103. package/build/types/object-table/hooks/useObjectTableData.d.ts.map +1 -1
  104. package/build/types/public/experimental/action-form.d.ts +1 -1
  105. package/build/types/public/experimental/action-form.d.ts.map +1 -1
  106. package/docs/FilterList.md +1 -1
  107. package/docs/ObjectTable.md +1 -1
  108. package/docs/Prerequisites.md +4 -4
  109. package/package.json +8 -8
  110. package/build/cjs/chunk-4OIHG235.cjs.map +0 -1
  111. package/build/cjs/chunk-FVA2OU7H.cjs.map +0 -1
  112. package/build/cjs/chunk-HV6Q2FFI.cjs.map +0 -1
  113. package/build/cjs/chunk-YUN7IILR.cjs.map +0 -1
package/AGENTS.md CHANGED
@@ -27,12 +27,12 @@ See `@osdk/react`'s `AGENTS.md` for optional peers (`@osdk/foundry.admin`, `@osd
27
27
 
28
28
  ## Install-time errors
29
29
 
30
- | Error | Cause | Fix |
31
- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
32
- | `"<name>" is not exported by @osdk/client/.../unstable-do-not-use.js` (or `@osdk/api/...`) | `@osdk/client` or `@osdk/api` or `@osdk/react` version mismatches what `@osdk/react-components` was built against | Do NOT delete the import or downgrade silently. Follow the CHANGELOG recipe in `## Installing` and pin all three peers to the exact versions listed. |
33
- | `"<name>" is not exported by @osdk/react/...` | `@osdk/react` version mismatches what `@osdk/react-components` was built against | Do NOT delete the import or downgrade silently. Follow the CHANGELOG recipe in `## Installing` and pin `@osdk/react` to the exact version listed. |
34
- | `Rollup failed to resolve import "@osdk/foundry.admin"` (or `@osdk/foundry.core`) | Transitive import from `@osdk/react/experimental/admin` without the optional peers | Install `@osdk/foundry.admin` + `@osdk/foundry.core`, OR avoid surfaces that use the admin hooks. |
35
- | pnpm/npm peer warning about `@osdk/client` or `@osdk/react` range | Declared peer ranges are broad; prerelease coupling is tighter | Follow the CHANGELOG recipe; pin to exact versions. |
30
+ | Error | Cause | Fix |
31
+ | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
32
+ | `"<name>" is not exported by @osdk/client/.../observable.js` (or `@osdk/client/.../unstable-do-not-use.js`, or `@osdk/api/...`) | `@osdk/client` or `@osdk/api` or `@osdk/react` version mismatches what `@osdk/react-components` was built against | Do NOT delete the import or downgrade silently. Follow the CHANGELOG recipe in `## Installing` and pin all three peers to the exact versions listed. |
33
+ | `"<name>" is not exported by @osdk/react/...` | `@osdk/react` version mismatches what `@osdk/react-components` was built against | Do NOT delete the import or downgrade silently. Follow the CHANGELOG recipe in `## Installing` and pin `@osdk/react` to the exact version listed. |
34
+ | `Rollup failed to resolve import "@osdk/foundry.admin"` (or `@osdk/foundry.core`) | Transitive import from `@osdk/react/platform-apis` without the optional peers | Install `@osdk/foundry.admin` + `@osdk/foundry.core`, OR avoid surfaces that use the admin hooks. |
35
+ | pnpm/npm peer warning about `@osdk/client` or `@osdk/react` range | Declared peer ranges are broad; prerelease coupling is tighter | Follow the CHANGELOG recipe; pin to exact versions. |
36
36
 
37
37
  ## Components
38
38
 
package/CHANGELOG.md CHANGED
@@ -1,22 +1,23 @@
1
1
  # @osdk/react-components
2
2
 
3
- ## 0.10.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
3
+ ## 0.10.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
+ - b355bc3: Add CONTRIBUTING.md for @osdk/react and @osdk/react-components
8
+ - 9b45e7b: Add form section support to BaseForm with collapsible groups, multi-column grid, and custom submit button
7
9
  - 3a4528c: Add ObjectSelect field for selecting object instances in action forms
10
+ - 5dc557e: Add helperText tooltip using Popover and widen type to React.ReactNode
8
11
 
9
12
  ### Patch Changes
10
13
 
11
- - b355bc3: Add CONTRIBUTING.md for @osdk/react and @osdk/react-components
12
- - 5dc557e: Add helperText tooltip using Popover and widen type to React.ReactNode
13
- - Updated dependencies [eb36e21]
14
+ - Updated dependencies [f747fa3]
15
+ - Updated dependencies [d892397]
14
16
  - Updated dependencies [c5a6047]
15
17
  - Updated dependencies [45be476]
16
18
  - Updated dependencies [b355bc3]
17
- - @osdk/client@2.14.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
18
- - @osdk/react@0.17.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
19
- - @osdk/api@2.14.0-main-5dc557e9e321d23e8e150e8015c41ebe3b6f387c
19
+ - Updated dependencies [20e9678]
20
+ - @osdk/react@0.17.0
20
21
 
21
22
  ## 0.9.0
22
23
 
package/README.md CHANGED
@@ -48,22 +48,22 @@ npm install react react-dom classnames @osdk/react @osdk/client @osdk/api
48
48
  **Prerequisites:**
49
49
 
50
50
  - A configured OSDK client
51
- - An OsdkProvider2 wrapping your application
51
+ - An OsdkProvider wrapping your application
52
52
 
53
53
  ## Setup
54
54
 
55
55
  ### App Setup
56
56
 
57
- **REQUIRED:** Wrap app with OsdkProvider2:
57
+ **REQUIRED:** Wrap app with OsdkProvider:
58
58
 
59
59
  ```tsx
60
60
  import { createClient } from "@osdk/client";
61
- import { OsdkProvider2 } from "@osdk/react/experimental";
61
+ import { OsdkProvider } from "@osdk/react";
62
62
 
63
63
  const client = createClient(/* config */);
64
64
 
65
65
  function App() {
66
- return <OsdkProvider2 client={client}>{/* components */}</OsdkProvider2>;
66
+ return <OsdkProvider client={client}>{/* components */}</OsdkProvider>;
67
67
  }
68
68
  ```
69
69
 
@@ -15,14 +15,14 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import { useOsdkMetadata } from "@osdk/react";
19
- import { useOsdkAction } from "@osdk/react/experimental";
18
+ import { useOsdkAction, useOsdkMetadata } from "@osdk/react";
20
19
  import React, { useCallback, useEffect, useMemo } from "react";
21
20
  import { typedReactMemo } from "../shared/typedMemo.js";
22
21
  import { BaseForm } from "./BaseForm.js";
23
22
  import { coerceFieldValue } from "./utils/coerceFieldValue.js";
24
23
  import { getDefaultFieldDefinitions } from "./utils/getDefaultFieldDefinitions.js";
25
24
  const EMPTY_FIELD_DEFINITIONS = [];
25
+ const EMPTY_FORM_CONTENT = [];
26
26
  export const ActionForm = typedReactMemo(function ({
27
27
  actionDefinition,
28
28
  formTitle,
@@ -68,6 +68,10 @@ export const ActionForm = typedReactMemo(function ({
68
68
  }));
69
69
  }, [formFieldDefinitions, parameters]);
70
70
  const rendererFieldDefinitions = useMemo(() => customFieldDefinitions ?? (metadata != null ? getDefaultFieldDefinitions(metadata) : EMPTY_FIELD_DEFINITIONS), [customFieldDefinitions, metadata]);
71
+ const formContent = useMemo(() => rendererFieldDefinitions.length === 0 ? EMPTY_FORM_CONTENT : rendererFieldDefinitions.map(def => ({
72
+ type: "field",
73
+ definition: def
74
+ })), [rendererFieldDefinitions]);
71
75
  const coerceFormState = useCallback(rawState => {
72
76
  const coerced = {};
73
77
  for (const [key, value] of Object.entries(rawState)) {
@@ -100,7 +104,7 @@ export const ActionForm = typedReactMemo(function ({
100
104
  const resolvedTitle = formTitle ?? metadata?.displayName ?? actionDefinition.apiName;
101
105
  const commonProps = {
102
106
  formTitle: resolvedTitle,
103
- fieldDefinitions: rendererFieldDefinitions,
107
+ formContent,
104
108
  onSubmit: handleSubmit,
105
109
  isSubmitDisabled,
106
110
  isPending,
@@ -1 +1 @@
1
- {"version":3,"file":"ActionForm.js","names":["useOsdkMetadata","useOsdkAction","React","useCallback","useEffect","useMemo","typedReactMemo","BaseForm","coerceFieldValue","getDefaultFieldDefinitions","EMPTY_FIELD_DEFINITIONS","ActionForm","actionDefinition","formTitle","formFieldDefinitions","formState","controlledFormState","onFormStateChange","isSubmitDisabled","onSubmit","onValidationResponse","_onValidationResponse","onSuccess","onError","applyAction","osdkApplyAction","isPending","metadata","loading","metadataLoading","error","metadataError","type","parameters","customFieldDefinitions","map","def","fieldKey","String","fieldType","defaultValue","rendererFieldDefinitions","coerceFormState","rawState","coerced","key","value","Object","entries","handleSubmit","rawFormState","result","e","handleFieldValueChange","prev","resolvedTitle","displayName","apiName","commonProps","fieldDefinitions","isLoading","onFieldValueChange","createElement","_extends"],"sources":["ActionForm.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ActionDefinition } from \"@osdk/api\";\nimport { useOsdkMetadata } from \"@osdk/react\";\nimport { useOsdkAction } from \"@osdk/react/experimental\";\nimport React, { useCallback, useEffect, useMemo } from \"react\";\nimport { typedReactMemo } from \"../shared/typedMemo.js\";\nimport type { ActionFormProps, FormState } from \"./ActionFormApi.js\";\nimport { BaseForm } from \"./BaseForm.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { coerceFieldValue } from \"./utils/coerceFieldValue.js\";\nimport { getDefaultFieldDefinitions } from \"./utils/getDefaultFieldDefinitions.js\";\n\nconst EMPTY_FIELD_DEFINITIONS: readonly [] = [];\n\nexport const ActionForm: <Q extends ActionDefinition<unknown>>(\n props: ActionFormProps<Q>,\n) => React.ReactElement = typedReactMemo(function ActionFormFn<\n Q extends ActionDefinition<unknown>,\n>({\n actionDefinition,\n formTitle,\n formFieldDefinitions,\n formState: controlledFormState,\n onFormStateChange,\n isSubmitDisabled,\n onSubmit,\n onValidationResponse: _onValidationResponse,\n onSuccess,\n onError,\n}: ActionFormProps<Q>): React.ReactElement {\n const { applyAction: osdkApplyAction, isPending } = useOsdkAction(\n actionDefinition,\n );\n const {\n metadata,\n loading: metadataLoading,\n error: metadataError,\n } = useOsdkMetadata(actionDefinition);\n\n useEffect(\n function saveMetadataError() {\n if (metadataError != null) {\n onError?.({ type: \"unknown\", error: metadataError });\n }\n },\n [metadataError, onError],\n );\n\n const parameters = metadata?.parameters;\n\n const customFieldDefinitions: ReadonlyArray<RendererFieldDefinition> | null =\n useMemo(() => {\n if (formFieldDefinitions == null) {\n return null;\n }\n // RendererFieldDefinition is a discriminated union keyed by fieldComponent.\n // TypeScript can't verify that the spread preserves the fieldComponent ↔\n // fieldComponentProps pairing, but FormFieldDefinition guarantees it.\n return formFieldDefinitions.map(\n (def) =>\n ({\n ...def,\n fieldKey: String(def.fieldKey),\n fieldType: parameters?.[String(def.fieldKey)]?.type,\n defaultValue: def.defaultValue,\n }) as RendererFieldDefinition,\n );\n }, [formFieldDefinitions, parameters]);\n\n const rendererFieldDefinitions = useMemo(\n () =>\n customFieldDefinitions\n ?? (metadata != null\n ? getDefaultFieldDefinitions(metadata)\n : EMPTY_FIELD_DEFINITIONS),\n [customFieldDefinitions, metadata],\n );\n\n const coerceFormState = useCallback(\n (rawState: Record<string, unknown>): Record<string, unknown> => {\n const coerced: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawState)) {\n coerced[key] = coerceFieldValue(parameters?.[key]?.type, value);\n }\n return coerced;\n },\n [parameters],\n );\n\n const handleSubmit = useCallback(\n async (rawFormState: Record<string, unknown>) => {\n const formState = coerceFormState(rawFormState) as FormState<Q>;\n try {\n if (onSubmit != null) {\n await onSubmit(formState, osdkApplyAction);\n } else {\n const result = await osdkApplyAction(formState);\n onSuccess?.(result);\n }\n } catch (e) {\n onError?.({ type: \"submission\", error: e });\n }\n },\n [coerceFormState, onSubmit, osdkApplyAction, onSuccess, onError],\n );\n\n const handleFieldValueChange = useCallback(\n (fieldKey: string, value: unknown) => {\n onFormStateChange?.(\n (prev) =>\n ({\n ...prev,\n [fieldKey]: value,\n }) as FormState<Q>,\n );\n },\n [onFormStateChange],\n );\n\n const resolvedTitle = formTitle ?? metadata?.displayName\n ?? actionDefinition.apiName;\n\n const isControlled = controlledFormState != null;\n\n const commonProps = {\n formTitle: resolvedTitle,\n fieldDefinitions: rendererFieldDefinitions,\n onSubmit: handleSubmit,\n isSubmitDisabled,\n isPending,\n isLoading: metadataLoading,\n onFieldValueChange: handleFieldValueChange,\n };\n\n if (!isControlled) {\n return <BaseForm {...commonProps} />;\n }\n\n return <BaseForm {...commonProps} formState={controlledFormState} />;\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ActionForm.js","names":["useOsdkAction","useOsdkMetadata","React","useCallback","useEffect","useMemo","typedReactMemo","BaseForm","coerceFieldValue","getDefaultFieldDefinitions","EMPTY_FIELD_DEFINITIONS","EMPTY_FORM_CONTENT","ActionForm","actionDefinition","formTitle","formFieldDefinitions","formState","controlledFormState","onFormStateChange","isSubmitDisabled","onSubmit","onValidationResponse","_onValidationResponse","onSuccess","onError","applyAction","osdkApplyAction","isPending","metadata","loading","metadataLoading","error","metadataError","type","parameters","customFieldDefinitions","map","def","fieldKey","String","fieldType","defaultValue","rendererFieldDefinitions","formContent","length","definition","coerceFormState","rawState","coerced","key","value","Object","entries","handleSubmit","rawFormState","result","e","handleFieldValueChange","prev","resolvedTitle","displayName","apiName","commonProps","isLoading","onFieldValueChange","createElement","_extends"],"sources":["ActionForm.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ActionDefinition } from \"@osdk/api\";\nimport { useOsdkAction, useOsdkMetadata } from \"@osdk/react\";\nimport React, { useCallback, useEffect, useMemo } from \"react\";\nimport { typedReactMemo } from \"../shared/typedMemo.js\";\nimport type {\n ActionFormProps,\n FormContentItem,\n FormState,\n} from \"./ActionFormApi.js\";\nimport { BaseForm } from \"./BaseForm.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { coerceFieldValue } from \"./utils/coerceFieldValue.js\";\nimport { getDefaultFieldDefinitions } from \"./utils/getDefaultFieldDefinitions.js\";\n\nconst EMPTY_FIELD_DEFINITIONS: ReadonlyArray<RendererFieldDefinition> = [];\nconst EMPTY_FORM_CONTENT: ReadonlyArray<FormContentItem> = [];\n\nexport const ActionForm: <Q extends ActionDefinition<unknown>>(\n props: ActionFormProps<Q>,\n) => React.ReactElement = typedReactMemo(function ActionFormFn<\n Q extends ActionDefinition<unknown>,\n>({\n actionDefinition,\n formTitle,\n formFieldDefinitions,\n formState: controlledFormState,\n onFormStateChange,\n isSubmitDisabled,\n onSubmit,\n onValidationResponse: _onValidationResponse,\n onSuccess,\n onError,\n}: ActionFormProps<Q>): React.ReactElement {\n const { applyAction: osdkApplyAction, isPending } = useOsdkAction(\n actionDefinition,\n );\n const {\n metadata,\n loading: metadataLoading,\n error: metadataError,\n } = useOsdkMetadata(actionDefinition);\n\n useEffect(\n function saveMetadataError() {\n if (metadataError != null) {\n onError?.({ type: \"unknown\", error: metadataError });\n }\n },\n [metadataError, onError],\n );\n\n const parameters = metadata?.parameters;\n\n const customFieldDefinitions: ReadonlyArray<RendererFieldDefinition> | null =\n useMemo(() => {\n if (formFieldDefinitions == null) {\n return null;\n }\n // RendererFieldDefinition is a discriminated union keyed by fieldComponent.\n // TypeScript can't verify that the spread preserves the fieldComponent ↔\n // fieldComponentProps pairing, but FormFieldDefinition guarantees it.\n return formFieldDefinitions.map(\n (def) =>\n ({\n ...def,\n fieldKey: String(def.fieldKey),\n fieldType: parameters?.[String(def.fieldKey)]?.type,\n defaultValue: def.defaultValue,\n }) as RendererFieldDefinition,\n );\n }, [formFieldDefinitions, parameters]);\n\n const rendererFieldDefinitions = useMemo(\n () =>\n customFieldDefinitions\n ?? (metadata != null\n ? getDefaultFieldDefinitions(metadata)\n : EMPTY_FIELD_DEFINITIONS),\n [customFieldDefinitions, metadata],\n );\n\n const formContent = useMemo(\n (): ReadonlyArray<FormContentItem> =>\n rendererFieldDefinitions.length === 0\n ? EMPTY_FORM_CONTENT\n : rendererFieldDefinitions.map(\n (def): FormContentItem => ({ type: \"field\", definition: def }),\n ),\n [rendererFieldDefinitions],\n );\n\n const coerceFormState = useCallback(\n (rawState: Record<string, unknown>): Record<string, unknown> => {\n const coerced: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawState)) {\n coerced[key] = coerceFieldValue(parameters?.[key]?.type, value);\n }\n return coerced;\n },\n [parameters],\n );\n\n const handleSubmit = useCallback(\n async (rawFormState: Record<string, unknown>) => {\n const formState = coerceFormState(rawFormState) as FormState<Q>;\n try {\n if (onSubmit != null) {\n await onSubmit(formState, osdkApplyAction);\n } else {\n const result = await osdkApplyAction(formState);\n onSuccess?.(result);\n }\n } catch (e) {\n onError?.({ type: \"submission\", error: e });\n }\n },\n [coerceFormState, onSubmit, osdkApplyAction, onSuccess, onError],\n );\n\n const handleFieldValueChange = useCallback(\n (fieldKey: string, value: unknown) => {\n onFormStateChange?.(\n (prev) =>\n ({\n ...prev,\n [fieldKey]: value,\n }) as FormState<Q>,\n );\n },\n [onFormStateChange],\n );\n\n const resolvedTitle = formTitle ?? metadata?.displayName\n ?? actionDefinition.apiName;\n\n const isControlled = controlledFormState != null;\n\n const commonProps = {\n formTitle: resolvedTitle,\n formContent,\n onSubmit: handleSubmit,\n isSubmitDisabled,\n isPending,\n isLoading: metadataLoading,\n onFieldValueChange: handleFieldValueChange,\n };\n\n if (!isControlled) {\n return <BaseForm {...commonProps} />;\n }\n\n return <BaseForm {...commonProps} formState={controlledFormState} />;\n});\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"ActionFormApi.js","names":[],"sources":["ActionFormApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n} from \"@osdk/api\";\nimport type { ActionValidationError } from \"@osdk/client\";\nimport type {\n ActionParameters,\n FieldKey,\n FieldValueType,\n FormFieldDefinition,\n RendererFieldDefinition,\n} from \"./FormFieldApi.js\";\n\n/**\n * Props for the ActionForm component.\n *\n * A discriminated union ensures that controlled mode (formState provided)\n * always requires onFormStateChange, and uncontrolled mode makes `onFormStateChange` optional\n */\nexport type ActionFormProps<Q extends ActionDefinition<unknown>> =\n | (ActionFormConfigProps<Q> & {\n formState: FormState<Q>;\n onFormStateChange: (\n updater: (prevState: FormState<Q>) => FormState<Q>,\n ) => void;\n })\n | (ActionFormConfigProps<Q> & {\n formState?: undefined;\n onFormStateChange?: (\n updater: (prevState: FormState<Q>) => FormState<Q>,\n ) => void;\n });\n\ninterface ActionFormConfigProps<Q extends ActionDefinition<unknown>>\n extends Pick<BaseFormProps, \"formTitle\" | \"isSubmitDisabled\">\n{\n actionDefinition: Q;\n\n /**\n * If not supplied, field definitions are constructed from `ActionParameters`.\n */\n formFieldDefinitions?: ReadonlyArray<FormFieldDefinition<Q>>;\n\n /**\n * If supplied, this will override the default submit action\n * By default, the action's applyAction will be called\n *\n * @param formState all field values when onSubmit is called\n * @param applyAction the function to execute the action\n * @returns a promise of the submission response\n */\n onSubmit?: (\n formState: FormState<Q>,\n applyAction: (\n args: ActionParameters<Q>,\n ) => Promise<ActionEditResponse | undefined>,\n ) => Promise<unknown> | void;\n\n /**\n * Called when the validation response is returned from a validateOnly submission\n *\n * @param results the validation response\n */\n onValidationResponse?: (results: ActionValidationResponse) => void;\n\n /**\n * Called when the action is successfully executed from a non-validateOnly submission\n *\n * @param results the submission response\n */\n onSuccess?: (results: ActionEditResponse | undefined) => void;\n\n /**\n * Called when there is an error in form submission\n *\n * @param error the error that occurred\n */\n onError?: (error: FormError) => void;\n}\n\n/**\n * Form values mapping parameter names to their values\n */\nexport type FormState<Q extends ActionDefinition<unknown>> = {\n [K in FieldKey<Q>]?: FieldValueType<Q, K>;\n};\n\n/**\n * Form error discriminated union\n */\nexport type FormError =\n | { type: \"validation\"; error: ActionValidationError }\n | { type: \"submission\"; error: unknown }\n | { type: \"unknown\"; error: unknown };\n\n/**\n * Props for the `BaseForm` component, which renders a form without\n * OSDK data fetching.\n *\n * Uses a discriminated union so that controlled mode (`formState` provided)\n * always requires `onFieldValueChange`, and uncontrolled mode omits both.\n * `onSubmit` receives the current form state so callers can access values\n * even in uncontrolled mode.\n */\nexport type BaseFormProps =\n & BaseFormCommonProps\n & (\n | {\n formState: Record<string, unknown>;\n onFieldValueChange: (fieldKey: string, value: unknown) => void;\n }\n | {\n formState?: undefined;\n onFieldValueChange?: (fieldKey: string, value: unknown) => void;\n }\n );\n\ninterface BaseFormCommonProps {\n formTitle?: string;\n fieldDefinitions: ReadonlyArray<RendererFieldDefinition>;\n onSubmit: (formState: Record<string, unknown>) => Promise<void> | void;\n isSubmitDisabled?: boolean;\n isPending?: boolean;\n isLoading?: boolean;\n className?: string;\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"ActionFormApi.js","names":[],"sources":["ActionFormApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n} from \"@osdk/api\";\nimport type { ActionValidationError } from \"@osdk/client\";\nimport type {\n ActionParameters,\n FieldKey,\n FieldValueType,\n FormFieldDefinition,\n RendererFieldDefinition,\n} from \"./FormFieldApi.js\";\n\n/**\n * Props for the ActionForm component.\n *\n * A discriminated union ensures that controlled mode (formState provided)\n * always requires onFormStateChange, and uncontrolled mode makes `onFormStateChange` optional\n */\nexport type ActionFormProps<Q extends ActionDefinition<unknown>> =\n | (ActionFormConfigProps<Q> & {\n formState: FormState<Q>;\n onFormStateChange: (\n updater: (prevState: FormState<Q>) => FormState<Q>,\n ) => void;\n })\n | (ActionFormConfigProps<Q> & {\n formState?: undefined;\n onFormStateChange?: (\n updater: (prevState: FormState<Q>) => FormState<Q>,\n ) => void;\n });\n\ninterface ActionFormConfigProps<Q extends ActionDefinition<unknown>>\n extends Pick<BaseFormProps, \"formTitle\" | \"isSubmitDisabled\">\n{\n actionDefinition: Q;\n\n /**\n * If not supplied, field definitions are constructed from `ActionParameters`.\n */\n formFieldDefinitions?: ReadonlyArray<FormFieldDefinition<Q>>;\n\n /**\n * If supplied, this will override the default submit action\n * By default, the action's applyAction will be called\n *\n * @param formState all field values when onSubmit is called\n * @param applyAction the function to execute the action\n * @returns a promise of the submission response\n */\n onSubmit?: (\n formState: FormState<Q>,\n applyAction: (\n args: ActionParameters<Q>,\n ) => Promise<ActionEditResponse | undefined>,\n ) => Promise<unknown> | void;\n\n /**\n * Called when the validation response is returned from a validateOnly submission\n *\n * @param results the validation response\n */\n onValidationResponse?: (results: ActionValidationResponse) => void;\n\n /**\n * Called when the action is successfully executed from a non-validateOnly submission\n *\n * @param results the submission response\n */\n onSuccess?: (results: ActionEditResponse | undefined) => void;\n\n /**\n * Called when there is an error in form submission\n *\n * @param error the error that occurred\n */\n onError?: (error: FormError) => void;\n}\n\n/**\n * Form values mapping parameter names to their values\n */\nexport type FormState<Q extends ActionDefinition<unknown>> = {\n [K in FieldKey<Q>]?: FieldValueType<Q, K>;\n};\n\n/**\n * Form error discriminated union\n */\nexport type FormError =\n | { type: \"validation\"; error: ActionValidationError }\n | { type: \"submission\"; error: unknown }\n | { type: \"unknown\"; error: unknown };\n\n/**\n * A single item in the form content array — either a standalone field\n * or a section that groups multiple fields.\n */\nexport type FormContentItem =\n | { type: \"field\"; definition: RendererFieldDefinition }\n | { type: \"section\"; key: string; definition: FormSectionDefinition };\n\n/**\n * Configuration for a form section — a visual group of fields with\n * optional title bar, collapse behavior, and multi-column layout.\n */\nexport interface FormSectionDefinition {\n title: string;\n description?: string;\n fields: ReadonlyArray<RendererFieldDefinition>;\n /** Whether the section starts collapsed. Default `false`. */\n collapsedByDefault?: boolean;\n /** Whether to show the title bar. Default `true`. */\n showTitleBar?: boolean;\n /** Number of columns for fields. Default `1`. */\n columnCount?: 1 | 2;\n /** Visual style. `\"box\"` = bordered card, `\"minimal\"` = heading only. Default `\"box\"`. */\n style?: \"box\" | \"minimal\";\n}\n\n/**\n * Props for the `BaseForm` component, which renders a form without\n * OSDK data fetching.\n *\n * Uses a discriminated union so that controlled mode (`formState` provided)\n * always requires `onFieldValueChange`, and uncontrolled mode omits both.\n * `onSubmit` receives the current form state so callers can access values\n * even in uncontrolled mode.\n */\nexport type BaseFormProps =\n & BaseFormCommonProps\n & (\n | {\n formState: Record<string, unknown>;\n onFieldValueChange: (fieldKey: string, value: unknown) => void;\n }\n | {\n formState?: undefined;\n onFieldValueChange?: (fieldKey: string, value: unknown) => void;\n }\n );\n\ninterface BaseFormCommonProps {\n formTitle?: string;\n formContent: ReadonlyArray<FormContentItem>;\n onSubmit: (formState: Record<string, unknown>) => Promise<void> | void;\n isSubmitDisabled?: boolean;\n isPending?: boolean;\n isLoading?: boolean;\n className?: string;\n /** Label for the submit button. Default `\"Submit\"`. */\n submitButtonText?: string;\n /** Visual variant of the submit button. Default `\"primary\"`. */\n submitButtonVariant?: \"primary\" | \"secondary\";\n}\n"],"mappings":"","ignoreList":[]}
@@ -25,18 +25,22 @@ import { useAsyncAction } from "../shared/hooks/useAsyncAction.js";
25
25
  import styles from "./BaseForm.module.css.js";
26
26
  import { FieldBridge } from "./fields/FieldBridge.js";
27
27
  import { FormHeader } from "./FormHeader.js";
28
+ import { FormSection } from "./FormSection.js";
28
29
  export const BaseForm = /*#__PURE__*/memo(function ({
29
30
  formTitle,
30
- fieldDefinitions,
31
+ formContent,
31
32
  formState: controlledFormState,
32
33
  onFieldValueChange,
33
34
  onSubmit,
34
35
  isSubmitDisabled = false,
35
36
  isPending = false,
36
37
  isLoading = false,
37
- className
38
+ className,
39
+ submitButtonText = "Submit",
40
+ submitButtonVariant = "primary"
38
41
  }) {
39
- const defaultValues = useMemo(() => buildDefaultValues(fieldDefinitions), [fieldDefinitions]);
42
+ const allFieldDefinitions = useMemo(() => flattenFieldDefinitions(formContent), [formContent]);
43
+ const defaultValues = useMemo(() => buildDefaultValues(allFieldDefinitions), [allFieldDefinitions]);
40
44
  const {
41
45
  control,
42
46
  trigger,
@@ -84,7 +88,7 @@ export const BaseForm = /*#__PURE__*/memo(function ({
84
88
  clearError();
85
89
  onFieldValueChange?.(fieldKey, value);
86
90
  }, [clearError, onFieldValueChange]);
87
- const labelByFieldKey = useMemo(() => new Map(fieldDefinitions.map(d => [d.fieldKey, d.label])), [fieldDefinitions]);
91
+ const labelByFieldKey = useMemo(() => new Map(allFieldDefinitions.map(d => [d.fieldKey, d.label])), [allFieldDefinitions]);
88
92
 
89
93
  // RHF reuses the same errors object reference across renders so we cannot memoize errorEntries
90
94
  const errorEntries = Object.entries(errors).map(([key, entry]) => ({
@@ -98,18 +102,33 @@ export const BaseForm = /*#__PURE__*/memo(function ({
98
102
  onSubmit: handleFormSubmit
99
103
  }, formTitle != null && /*#__PURE__*/React.createElement(FormHeader, {
100
104
  title: formTitle
101
- }), isLoading && fieldDefinitions.length === 0 && /*#__PURE__*/React.createElement("div", {
105
+ }), isLoading && allFieldDefinitions.length === 0 && /*#__PURE__*/React.createElement("div", {
102
106
  role: "status",
103
107
  "aria-label": "Loading form fields",
104
108
  className: styles.osdkFormFields
105
109
  }, FORM_SKELETON), /*#__PURE__*/React.createElement("div", {
106
110
  className: styles.osdkFormFields
107
- }, fieldDefinitions.map(fieldDef => /*#__PURE__*/React.createElement(FieldBridge, {
108
- key: fieldDef.fieldKey,
109
- fieldDef: fieldDef,
110
- control: control,
111
- onExternalChange: handleFieldChange
112
- }))), /*#__PURE__*/React.createElement("div", {
111
+ }, formContent.map(item => {
112
+ if (item.type === "field") {
113
+ return /*#__PURE__*/React.createElement(FieldBridge, {
114
+ key: item.definition.fieldKey,
115
+ fieldDef: item.definition,
116
+ control: control,
117
+ onExternalChange: handleFieldChange
118
+ });
119
+ }
120
+ const sectionErrorCount = item.definition.fields.reduce((count, field) => count + (errors[field.fieldKey] != null ? 1 : 0), 0);
121
+ return /*#__PURE__*/React.createElement(FormSection, {
122
+ key: item.key,
123
+ definition: item.definition,
124
+ errorCount: sectionErrorCount
125
+ }, item.definition.fields.map(fieldDef => /*#__PURE__*/React.createElement(FieldBridge, {
126
+ key: fieldDef.fieldKey,
127
+ fieldDef: fieldDef,
128
+ control: control,
129
+ onExternalChange: handleFieldChange
130
+ })));
131
+ })), /*#__PURE__*/React.createElement("div", {
113
132
  className: styles.osdkFormFooter
114
133
  }, /*#__PURE__*/React.createElement(ErrorIndicator, {
115
134
  errorEntries: errorEntries
@@ -118,9 +137,31 @@ export const BaseForm = /*#__PURE__*/memo(function ({
118
137
  }, /*#__PURE__*/React.createElement(SubmitButton, {
119
138
  isPending: isPending || isSubmitting,
120
139
  isSubmitDisabled: isSubmitDisabled || hasAttemptedSubmit && areErrorsPresent,
121
- errorMessage: buttonErrorMessage
140
+ errorMessage: buttonErrorMessage,
141
+ buttonText: submitButtonText,
142
+ buttonVariant: submitButtonVariant
122
143
  }))));
123
144
  });
145
+
146
+ /**
147
+ * Extracts all RendererFieldDefinitions from formContent, flattening
148
+ * section fields into a single array. RHF sees a flat field namespace
149
+ * regardless of visual grouping, so this is used to build default values
150
+ * and the field-key-to-label map for error display.
151
+ */
152
+ function flattenFieldDefinitions(formContent) {
153
+ const result = [];
154
+ for (const item of formContent) {
155
+ if (item.type === "field") {
156
+ result.push(item.definition);
157
+ } else {
158
+ for (const fieldDef of item.definition.fields) {
159
+ result.push(fieldDef);
160
+ }
161
+ }
162
+ }
163
+ return result;
164
+ }
124
165
  const SKELETON_FIELD_COUNT = 3;
125
166
 
126
167
  // Mimics the label + input layout of real form fields.
@@ -147,12 +188,14 @@ function buildDefaultValues(fieldDefinitions) {
147
188
  const SubmitButton = /*#__PURE__*/memo(function ({
148
189
  isPending,
149
190
  isSubmitDisabled,
150
- errorMessage
191
+ errorMessage,
192
+ buttonText,
193
+ buttonVariant
151
194
  }) {
152
- const buttonLabel = isPending ? "Submitting\u2026" : "Submit";
195
+ const buttonLabel = isPending ? "Submitting\u2026" : buttonText;
153
196
  const button = /*#__PURE__*/React.createElement(ActionButton, {
154
197
  type: "submit",
155
- variant: "primary",
198
+ variant: buttonVariant,
156
199
  disabled: isSubmitDisabled || isPending
157
200
  }, buttonLabel);
158
201
  if (errorMessage == null) {
@@ -1 +1 @@
1
- {"version":3,"file":"BaseForm.js","names":["Error","ErrorIcon","classNames","React","memo","useCallback","useMemo","useState","useForm","ActionButton","SkeletonBar","Tooltip","useAsyncAction","styles","FieldBridge","FormHeader","BaseForm","formTitle","fieldDefinitions","formState","controlledFormState","onFieldValueChange","onSubmit","isSubmitDisabled","isPending","isLoading","className","defaultValues","buildDefaultValues","control","trigger","getValues","errors","mode","values","hasAttemptedSubmit","setHasAttemptedSubmit","isSubmitting","error","submissionError","execute","executeSubmit","clearError","submissionErrorMessage","message","undefined","handleFormSubmit","e","preventDefault","isValid","handleFieldChange","fieldKey","value","labelByFieldKey","Map","map","d","label","errorEntries","Object","entries","key","entry","get","areErrorsPresent","length","buttonErrorMessage","createElement","osdkForm","title","role","osdkFormFields","FORM_SKELETON","fieldDef","onExternalChange","osdkFormFooter","ErrorIndicator","osdkFormSubmitButton","SubmitButton","errorMessage","SKELETON_FIELD_COUNT","Array","from","_","i","osdkFormSkeletonField","osdkFormSkeletonLabel","osdkFormSkeletonInput","def","props","fieldComponentProps","defaultValue","buttonLabel","button","type","variant","disabled","Root","defaultOpen","Trigger","render","osdkTooltipTriggerWrapper","Portal","Positioner","Popup","Arrow","count","osdkFormErrorIndicator","size","osdkFormErrorList"],"sources":["BaseForm.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Error as ErrorIcon } from \"@blueprintjs/icons\";\nimport classNames from \"classnames\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { SkeletonBar } from \"../base-components/skeleton/SkeletonBar.js\";\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { useAsyncAction } from \"../shared/hooks/useAsyncAction.js\";\nimport type { BaseFormProps } from \"./ActionFormApi.js\";\nimport styles from \"./BaseForm.module.css\";\nimport { FieldBridge } from \"./fields/FieldBridge.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { FormHeader } from \"./FormHeader.js\";\n\nexport const BaseForm: React.FC<BaseFormProps> = memo(function BaseFormFn({\n formTitle,\n fieldDefinitions,\n formState: controlledFormState,\n onFieldValueChange,\n onSubmit,\n isSubmitDisabled = false,\n isPending = false,\n isLoading = false,\n className,\n}: BaseFormProps): React.ReactElement {\n const isControlled = controlledFormState != null;\n\n const defaultValues = useMemo(\n () => buildDefaultValues(fieldDefinitions),\n [fieldDefinitions],\n );\n\n const {\n control,\n trigger,\n getValues,\n formState: { errors },\n } = useForm<Record<string, unknown>>({\n // Validate on blur first, then revalidate on change after the first\n // error. This gives the user a chance to finish typing before seeing\n // errors, while staying responsive once an error is surfaced.\n mode: \"onTouched\",\n ...(isControlled ? { values: controlledFormState } : { defaultValues }),\n });\n\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n\n const {\n isPending: isSubmitting,\n error: submissionError,\n execute: executeSubmit,\n clearError,\n } = useAsyncAction(onSubmit);\n const submissionErrorMessage = submissionError != null\n ? submissionError instanceof Error\n ? submissionError.message\n // TODO: provide better error message\n : \"Submission failed\"\n : undefined;\n\n const handleFormSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n setHasAttemptedSubmit(true);\n\n const isValid = await trigger();\n if (!isValid) {\n return;\n }\n\n // In controlled mode, always submit the controlled state, not RHF's\n // internal state. Between a user keystroke and the parent re-rendering,\n // RHF's store may hold the user-typed value rather than the parent's\n // value. Using controlledFormState directly preserves the existing\n // guarantee that controlled mode submits the parent's state.\n await executeSubmit(controlledFormState ?? getValues());\n },\n [trigger, executeSubmit, controlledFormState, getValues],\n );\n\n const handleFieldChange = useCallback(\n (fieldKey: string, value: unknown) => {\n clearError();\n onFieldValueChange?.(fieldKey, value);\n },\n [clearError, onFieldValueChange],\n );\n\n const isFormPending = isPending || isSubmitting;\n\n const labelByFieldKey = useMemo(\n () => new Map(fieldDefinitions.map((d) => [d.fieldKey, d.label])),\n [fieldDefinitions],\n );\n\n // RHF reuses the same errors object reference across renders so we cannot memoize errorEntries\n const errorEntries = Object.entries(errors).map(([key, entry]) => ({\n label: labelByFieldKey.get(key) ?? key,\n message: entry?.message ?? \"Invalid\",\n }));\n const areErrorsPresent = errorEntries.length > 0;\n const buttonErrorMessage = areErrorsPresent\n ? \"Some fields are invalid\"\n : submissionErrorMessage;\n\n return (\n <form\n className={classNames(styles.osdkForm, className)}\n onSubmit={handleFormSubmit}\n >\n {formTitle != null && <FormHeader title={formTitle} />}\n {isLoading && fieldDefinitions.length === 0 && (\n <div\n role=\"status\"\n aria-label=\"Loading form fields\"\n className={styles.osdkFormFields}\n >\n {FORM_SKELETON}\n </div>\n )}\n <div className={styles.osdkFormFields}>\n {fieldDefinitions.map((fieldDef) => (\n <FieldBridge\n key={fieldDef.fieldKey}\n fieldDef={fieldDef}\n control={control}\n onExternalChange={handleFieldChange}\n />\n ))}\n </div>\n <div className={styles.osdkFormFooter}>\n <ErrorIndicator errorEntries={errorEntries} />\n <div className={styles.osdkFormSubmitButton}>\n <SubmitButton\n isPending={isFormPending}\n isSubmitDisabled={isSubmitDisabled\n || (hasAttemptedSubmit && areErrorsPresent)}\n errorMessage={buttonErrorMessage}\n />\n </div>\n </div>\n </form>\n );\n});\n\nconst SKELETON_FIELD_COUNT = 3;\n\n// Mimics the label + input layout of real form fields.\nconst FORM_SKELETON = Array.from(\n { length: SKELETON_FIELD_COUNT },\n (_, i) => (\n <div key={i} className={styles.osdkFormSkeletonField}>\n <SkeletonBar className={styles.osdkFormSkeletonLabel} />\n <SkeletonBar className={styles.osdkFormSkeletonInput} />\n </div>\n ),\n);\n\nfunction buildDefaultValues(\n fieldDefinitions: ReadonlyArray<RendererFieldDefinition>,\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const def of fieldDefinitions) {\n const props: Record<string, unknown> = def.fieldComponentProps;\n if (\"defaultValue\" in props) {\n values[def.fieldKey] = props.defaultValue;\n }\n }\n return values;\n}\n\ninterface ErrorEntry {\n label: string;\n message: string;\n}\n\ninterface SubmitButtonProps {\n isPending: boolean;\n isSubmitDisabled: boolean;\n errorMessage: string | undefined;\n}\n\nconst SubmitButton = memo(function SubmitButtonFn({\n isPending,\n isSubmitDisabled,\n errorMessage,\n}: SubmitButtonProps): React.ReactElement {\n const buttonLabel = isPending ? \"Submitting\\u2026\" : \"Submit\";\n const button = (\n <ActionButton\n type=\"submit\"\n variant=\"primary\"\n disabled={isSubmitDisabled || isPending}\n >\n {buttonLabel}\n </ActionButton>\n );\n\n if (errorMessage == null) {\n return button;\n }\n\n return (\n <Tooltip.Root defaultOpen={true}>\n <Tooltip.Trigger\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {button}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n {errorMessage}\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n});\n\ninterface ErrorIndicatorProps {\n errorEntries: ReadonlyArray<ErrorEntry>;\n}\n\n// memo omitted: errorEntries is always a new array (RHF reuses the same errors ref)\nfunction ErrorIndicator({\n errorEntries,\n}: ErrorIndicatorProps): React.ReactElement | null {\n if (errorEntries.length === 0) {\n return null;\n }\n\n const count = errorEntries.length;\n\n return (\n <Tooltip.Root>\n <Tooltip.Trigger>\n <span className={styles.osdkFormErrorIndicator}>\n <ErrorIcon size={14} />\n {count === 1 ? \"1 issue\" : `${count} issues`}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n <ul className={styles.osdkFormErrorList}>\n {errorEntries.map((entry) => (\n <li key={entry.label}>\n <strong>{entry.label}:</strong> {entry.message}\n </li>\n ))}\n </ul>\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"BaseForm.js","names":["Error","ErrorIcon","classNames","React","memo","useCallback","useMemo","useState","useForm","ActionButton","SkeletonBar","Tooltip","useAsyncAction","styles","FieldBridge","FormHeader","FormSection","BaseForm","formTitle","formContent","formState","controlledFormState","onFieldValueChange","onSubmit","isSubmitDisabled","isPending","isLoading","className","submitButtonText","submitButtonVariant","allFieldDefinitions","flattenFieldDefinitions","defaultValues","buildDefaultValues","control","trigger","getValues","errors","mode","values","hasAttemptedSubmit","setHasAttemptedSubmit","isSubmitting","error","submissionError","execute","executeSubmit","clearError","submissionErrorMessage","message","undefined","handleFormSubmit","e","preventDefault","isValid","handleFieldChange","fieldKey","value","labelByFieldKey","Map","map","d","label","errorEntries","Object","entries","key","entry","get","areErrorsPresent","length","buttonErrorMessage","createElement","osdkForm","title","role","osdkFormFields","FORM_SKELETON","item","type","definition","fieldDef","onExternalChange","sectionErrorCount","fields","reduce","count","field","errorCount","osdkFormFooter","ErrorIndicator","osdkFormSubmitButton","SubmitButton","errorMessage","buttonText","buttonVariant","result","push","SKELETON_FIELD_COUNT","Array","from","_","i","osdkFormSkeletonField","osdkFormSkeletonLabel","osdkFormSkeletonInput","fieldDefinitions","def","props","fieldComponentProps","defaultValue","buttonLabel","button","variant","disabled","Root","defaultOpen","Trigger","render","osdkTooltipTriggerWrapper","Portal","Positioner","Popup","Arrow","osdkFormErrorIndicator","size","osdkFormErrorList"],"sources":["BaseForm.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Error as ErrorIcon } from \"@blueprintjs/icons\";\nimport classNames from \"classnames\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { SkeletonBar } from \"../base-components/skeleton/SkeletonBar.js\";\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { useAsyncAction } from \"../shared/hooks/useAsyncAction.js\";\nimport type { BaseFormProps, FormContentItem } from \"./ActionFormApi.js\";\nimport styles from \"./BaseForm.module.css\";\nimport { FieldBridge } from \"./fields/FieldBridge.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { FormHeader } from \"./FormHeader.js\";\nimport { FormSection } from \"./FormSection.js\";\n\nexport const BaseForm: React.FC<BaseFormProps> = memo(function BaseFormFn({\n formTitle,\n formContent,\n formState: controlledFormState,\n onFieldValueChange,\n onSubmit,\n isSubmitDisabled = false,\n isPending = false,\n isLoading = false,\n className,\n submitButtonText = \"Submit\",\n submitButtonVariant = \"primary\",\n}: BaseFormProps): React.ReactElement {\n const isControlled = controlledFormState != null;\n\n const allFieldDefinitions = useMemo(\n () => flattenFieldDefinitions(formContent),\n [formContent],\n );\n\n const defaultValues = useMemo(\n () => buildDefaultValues(allFieldDefinitions),\n [allFieldDefinitions],\n );\n\n const {\n control,\n trigger,\n getValues,\n formState: { errors },\n } = useForm<Record<string, unknown>>({\n // Validate on blur first, then revalidate on change after the first\n // error. This gives the user a chance to finish typing before seeing\n // errors, while staying responsive once an error is surfaced.\n mode: \"onTouched\",\n ...(isControlled ? { values: controlledFormState } : { defaultValues }),\n });\n\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n\n const {\n isPending: isSubmitting,\n error: submissionError,\n execute: executeSubmit,\n clearError,\n } = useAsyncAction(onSubmit);\n const submissionErrorMessage = submissionError != null\n ? submissionError instanceof Error\n ? submissionError.message\n // TODO: provide better error message\n : \"Submission failed\"\n : undefined;\n\n const handleFormSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n setHasAttemptedSubmit(true);\n\n const isValid = await trigger();\n if (!isValid) {\n return;\n }\n\n // In controlled mode, always submit the controlled state, not RHF's\n // internal state. Between a user keystroke and the parent re-rendering,\n // RHF's store may hold the user-typed value rather than the parent's\n // value. Using controlledFormState directly preserves the existing\n // guarantee that controlled mode submits the parent's state.\n await executeSubmit(controlledFormState ?? getValues());\n },\n [trigger, executeSubmit, controlledFormState, getValues],\n );\n\n const handleFieldChange = useCallback(\n (fieldKey: string, value: unknown) => {\n clearError();\n onFieldValueChange?.(fieldKey, value);\n },\n [clearError, onFieldValueChange],\n );\n\n const isFormPending = isPending || isSubmitting;\n\n const labelByFieldKey = useMemo(\n () => new Map(allFieldDefinitions.map((d) => [d.fieldKey, d.label])),\n [allFieldDefinitions],\n );\n\n // RHF reuses the same errors object reference across renders so we cannot memoize errorEntries\n const errorEntries = Object.entries(errors).map(([key, entry]) => ({\n label: labelByFieldKey.get(key) ?? key,\n message: entry?.message ?? \"Invalid\",\n }));\n const areErrorsPresent = errorEntries.length > 0;\n const buttonErrorMessage = areErrorsPresent\n ? \"Some fields are invalid\"\n : submissionErrorMessage;\n\n return (\n <form\n className={classNames(styles.osdkForm, className)}\n onSubmit={handleFormSubmit}\n >\n {formTitle != null && <FormHeader title={formTitle} />}\n {isLoading && allFieldDefinitions.length === 0 && (\n <div\n role=\"status\"\n aria-label=\"Loading form fields\"\n className={styles.osdkFormFields}\n >\n {FORM_SKELETON}\n </div>\n )}\n <div className={styles.osdkFormFields}>\n {formContent.map((item) => {\n if (item.type === \"field\") {\n return (\n <FieldBridge\n key={item.definition.fieldKey}\n fieldDef={item.definition}\n control={control}\n onExternalChange={handleFieldChange}\n />\n );\n }\n const sectionErrorCount = item.definition.fields.reduce(\n (count, field) => count + (errors[field.fieldKey] != null ? 1 : 0),\n 0,\n );\n return (\n <FormSection\n key={item.key}\n definition={item.definition}\n errorCount={sectionErrorCount}\n >\n {item.definition.fields.map((fieldDef) => (\n <FieldBridge\n key={fieldDef.fieldKey}\n fieldDef={fieldDef}\n control={control}\n onExternalChange={handleFieldChange}\n />\n ))}\n </FormSection>\n );\n })}\n </div>\n <div className={styles.osdkFormFooter}>\n <ErrorIndicator errorEntries={errorEntries} />\n <div className={styles.osdkFormSubmitButton}>\n <SubmitButton\n isPending={isFormPending}\n isSubmitDisabled={isSubmitDisabled\n || (hasAttemptedSubmit && areErrorsPresent)}\n errorMessage={buttonErrorMessage}\n buttonText={submitButtonText}\n buttonVariant={submitButtonVariant}\n />\n </div>\n </div>\n </form>\n );\n});\n\n/**\n * Extracts all RendererFieldDefinitions from formContent, flattening\n * section fields into a single array. RHF sees a flat field namespace\n * regardless of visual grouping, so this is used to build default values\n * and the field-key-to-label map for error display.\n */\nfunction flattenFieldDefinitions(\n formContent: ReadonlyArray<FormContentItem>,\n): ReadonlyArray<RendererFieldDefinition> {\n const result: RendererFieldDefinition[] = [];\n for (const item of formContent) {\n if (item.type === \"field\") {\n result.push(item.definition);\n } else {\n for (const fieldDef of item.definition.fields) {\n result.push(fieldDef);\n }\n }\n }\n return result;\n}\n\nconst SKELETON_FIELD_COUNT = 3;\n\n// Mimics the label + input layout of real form fields.\nconst FORM_SKELETON = Array.from(\n { length: SKELETON_FIELD_COUNT },\n (_, i) => (\n <div key={i} className={styles.osdkFormSkeletonField}>\n <SkeletonBar className={styles.osdkFormSkeletonLabel} />\n <SkeletonBar className={styles.osdkFormSkeletonInput} />\n </div>\n ),\n);\n\nfunction buildDefaultValues(\n fieldDefinitions: ReadonlyArray<RendererFieldDefinition>,\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const def of fieldDefinitions) {\n const props: Record<string, unknown> = def.fieldComponentProps;\n if (\"defaultValue\" in props) {\n values[def.fieldKey] = props.defaultValue;\n }\n }\n return values;\n}\n\ninterface ErrorEntry {\n label: string;\n message: string;\n}\n\ninterface SubmitButtonProps {\n isPending: boolean;\n isSubmitDisabled: boolean;\n errorMessage: string | undefined;\n buttonText: string;\n buttonVariant: \"primary\" | \"secondary\";\n}\n\nconst SubmitButton = memo(function SubmitButtonFn({\n isPending,\n isSubmitDisabled,\n errorMessage,\n buttonText,\n buttonVariant,\n}: SubmitButtonProps): React.ReactElement {\n const buttonLabel = isPending ? \"Submitting\\u2026\" : buttonText;\n const button = (\n <ActionButton\n type=\"submit\"\n variant={buttonVariant}\n disabled={isSubmitDisabled || isPending}\n >\n {buttonLabel}\n </ActionButton>\n );\n\n if (errorMessage == null) {\n return button;\n }\n\n return (\n <Tooltip.Root defaultOpen={true}>\n <Tooltip.Trigger\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {button}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n {errorMessage}\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n});\n\ninterface ErrorIndicatorProps {\n errorEntries: ReadonlyArray<ErrorEntry>;\n}\n\n// memo omitted: errorEntries is always a new array (RHF reuses the same errors ref)\nfunction ErrorIndicator({\n errorEntries,\n}: ErrorIndicatorProps): React.ReactElement | null {\n if (errorEntries.length === 0) {\n return null;\n }\n\n const count = errorEntries.length;\n\n return (\n <Tooltip.Root>\n <Tooltip.Trigger>\n <span className={styles.osdkFormErrorIndicator}>\n <ErrorIcon size={14} />\n {count === 1 ? \"1 issue\" : `${count} issues`}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n <ul className={styles.osdkFormErrorList}>\n {errorEntries.map((entry) => (\n <li key={entry.label}>\n <strong>{entry.label}:</strong> {entry.message}\n </li>\n ))}\n </ul>\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { Collapsible } from "@base-ui/react/collapsible";
18
+ import { CaretDown } from "@blueprintjs/icons";
19
+ import classNames from "classnames";
20
+ import React, { memo } from "react";
21
+ import styles from "./FormSection.module.css.js";
22
+ export const FormSection = /*#__PURE__*/memo(function ({
23
+ definition,
24
+ errorCount,
25
+ children
26
+ }) {
27
+ const {
28
+ title,
29
+ description,
30
+ collapsedByDefault = false,
31
+ showTitleBar = true,
32
+ columnCount = 1,
33
+ style = "box"
34
+ } = definition;
35
+ if (style === "minimal") {
36
+ return /*#__PURE__*/React.createElement(MinimalSection, {
37
+ title: title,
38
+ description: description
39
+ }, children);
40
+ }
41
+ const contentClassName = classNames(columnCount === 2 ? styles.osdkFormSectionGrid : styles.osdkFormSectionContent, styles.osdkFormSectionDivider);
42
+ if (!showTitleBar) {
43
+ return /*#__PURE__*/React.createElement("div", {
44
+ className: styles.osdkFormSectionBox
45
+ }, /*#__PURE__*/React.createElement("div", {
46
+ className: contentClassName
47
+ }, children));
48
+ }
49
+ return /*#__PURE__*/React.createElement(Collapsible.Root, {
50
+ // Inverted: Base UI uses "open" semantics, our API uses "collapsed" semantics
51
+ defaultOpen: !collapsedByDefault,
52
+ className: styles.osdkFormSectionBox
53
+ }, /*#__PURE__*/React.createElement("div", {
54
+ className: styles.osdkFormSectionHeader
55
+ }, /*#__PURE__*/React.createElement("div", {
56
+ className: styles.osdkFormSectionTitleArea
57
+ }, /*#__PURE__*/React.createElement("span", {
58
+ className: styles.osdkFormSectionTitle
59
+ }, title), description != null && /*#__PURE__*/React.createElement("span", {
60
+ className: styles.osdkFormSectionDescription
61
+ }, description)), /*#__PURE__*/React.createElement(Collapsible.Trigger, {
62
+ className: styles.osdkFormSectionTrigger,
63
+ "aria-label": title
64
+ }, errorCount > 0 && /*#__PURE__*/React.createElement("span", {
65
+ className: styles.osdkFormSectionErrorBadge,
66
+ role: "status"
67
+ }, errorCount === 1 ? "1 error" : `${errorCount} errors`), /*#__PURE__*/React.createElement("span", {
68
+ className: styles.osdkFormSectionChevron
69
+ }, /*#__PURE__*/React.createElement(CaretDown, {
70
+ size: 16
71
+ })))), /*#__PURE__*/React.createElement(Collapsible.Panel, {
72
+ keepMounted: true
73
+ }, /*#__PURE__*/React.createElement("div", {
74
+ className: contentClassName
75
+ }, children)));
76
+ });
77
+ const MinimalSection = /*#__PURE__*/memo(function ({
78
+ title,
79
+ description,
80
+ children
81
+ }) {
82
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
83
+ className: styles.osdkFormSectionMinimalHeader
84
+ }, /*#__PURE__*/React.createElement("div", {
85
+ className: styles.osdkFormSectionMinimalTitle
86
+ }, title), description != null && /*#__PURE__*/React.createElement("div", {
87
+ className: styles.osdkFormSectionMinimalDescription
88
+ }, description)), /*#__PURE__*/React.createElement("div", {
89
+ className: styles.osdkFormSectionMinimalContent
90
+ }, children));
91
+ });
92
+ //# sourceMappingURL=FormSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormSection.js","names":["Collapsible","CaretDown","classNames","React","memo","styles","FormSection","definition","errorCount","children","title","description","collapsedByDefault","showTitleBar","columnCount","style","createElement","MinimalSection","contentClassName","osdkFormSectionGrid","osdkFormSectionContent","osdkFormSectionDivider","className","osdkFormSectionBox","Root","defaultOpen","osdkFormSectionHeader","osdkFormSectionTitleArea","osdkFormSectionTitle","osdkFormSectionDescription","Trigger","osdkFormSectionTrigger","osdkFormSectionErrorBadge","role","osdkFormSectionChevron","size","Panel","keepMounted","osdkFormSectionMinimalHeader","osdkFormSectionMinimalTitle","osdkFormSectionMinimalDescription","osdkFormSectionMinimalContent"],"sources":["FormSection.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Collapsible } from \"@base-ui/react/collapsible\";\nimport { CaretDown } from \"@blueprintjs/icons\";\nimport classNames from \"classnames\";\nimport React, { memo } from \"react\";\nimport type { FormSectionDefinition } from \"./ActionFormApi.js\";\nimport styles from \"./FormSection.module.css\";\n\nexport interface FormSectionProps {\n definition: FormSectionDefinition;\n errorCount: number;\n children: React.ReactNode;\n}\n\nexport const FormSection: React.NamedExoticComponent<FormSectionProps> = memo(\n function FormSectionFn({\n definition,\n errorCount,\n children,\n }: FormSectionProps): React.ReactElement {\n const {\n title,\n description,\n collapsedByDefault = false,\n showTitleBar = true,\n columnCount = 1,\n style = \"box\",\n } = definition;\n\n const isMinimal = style === \"minimal\";\n\n if (isMinimal) {\n return (\n <MinimalSection title={title} description={description}>\n {children}\n </MinimalSection>\n );\n }\n\n const contentClassName = classNames(\n columnCount === 2\n ? styles.osdkFormSectionGrid\n : styles.osdkFormSectionContent,\n styles.osdkFormSectionDivider,\n );\n\n if (!showTitleBar) {\n return (\n <div className={styles.osdkFormSectionBox}>\n <div className={contentClassName}>{children}</div>\n </div>\n );\n }\n\n return (\n <Collapsible.Root\n // Inverted: Base UI uses \"open\" semantics, our API uses \"collapsed\" semantics\n defaultOpen={!collapsedByDefault}\n className={styles.osdkFormSectionBox}\n >\n <div className={styles.osdkFormSectionHeader}>\n <div className={styles.osdkFormSectionTitleArea}>\n <span className={styles.osdkFormSectionTitle}>{title}</span>\n {description != null && (\n <span className={styles.osdkFormSectionDescription}>\n {description}\n </span>\n )}\n </div>\n <Collapsible.Trigger\n className={styles.osdkFormSectionTrigger}\n aria-label={title}\n >\n {errorCount > 0 && (\n <span className={styles.osdkFormSectionErrorBadge} role=\"status\">\n {errorCount === 1 ? \"1 error\" : `${errorCount} errors`}\n </span>\n )}\n <span className={styles.osdkFormSectionChevron}>\n <CaretDown size={16} />\n </span>\n </Collapsible.Trigger>\n </div>\n {/* keepMounted: RHF needs fields in the DOM even when collapsed for validation */}\n <Collapsible.Panel keepMounted={true}>\n <div className={contentClassName}>{children}</div>\n </Collapsible.Panel>\n </Collapsible.Root>\n );\n },\n);\n\ninterface MinimalSectionProps {\n title: string;\n description: string | undefined;\n children: React.ReactNode;\n}\n\nconst MinimalSection = memo(function MinimalSectionFn({\n title,\n description,\n children,\n}: MinimalSectionProps): React.ReactElement {\n return (\n <div>\n <div className={styles.osdkFormSectionMinimalHeader}>\n <div className={styles.osdkFormSectionMinimalTitle}>{title}</div>\n {description != null && (\n <div className={styles.osdkFormSectionMinimalDescription}>\n {description}\n </div>\n )}\n </div>\n <div className={styles.osdkFormSectionMinimalContent}>{children}</div>\n </div>\n );\n});\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,WAAW,QAAQ,4BAA4B;AACxD,SAASC,SAAS,QAAQ,oBAAoB;AAC9C,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAOC,KAAK,IAAIC,IAAI,QAAQ,OAAO;AAEnC,OAAOC,MAAM,MAAM,0BAA0B;AAQ7C,OAAO,MAAMC,WAAyD,gBAAGF,IAAI,CAC3E,UAAuB;EACrBG,UAAU;EACVC,UAAU;EACVC;AACgB,CAAC,EAAsB;EACvC,MAAM;IACJC,KAAK;IACLC,WAAW;IACXC,kBAAkB,GAAG,KAAK;IAC1BC,YAAY,GAAG,IAAI;IACnBC,WAAW,GAAG,CAAC;IACfC,KAAK,GAAG;EACV,CAAC,GAAGR,UAAU;EAId,IAFkBQ,KAAK,KAAK,SAAS,EAEtB;IACb,oBACEZ,KAAA,CAAAa,aAAA,CAACC,cAAc;MAACP,KAAK,EAAEA,KAAM;MAACC,WAAW,EAAEA;IAAY,GACpDF,QACa,CAAC;EAErB;EAEA,MAAMS,gBAAgB,GAAGhB,UAAU,CACjCY,WAAW,KAAK,CAAC,GACbT,MAAM,CAACc,mBAAmB,GAC1Bd,MAAM,CAACe,sBAAsB,EACjCf,MAAM,CAACgB,sBACT,CAAC;EAED,IAAI,CAACR,YAAY,EAAE;IACjB,oBACEV,KAAA,CAAAa,aAAA;MAAKM,SAAS,EAAEjB,MAAM,CAACkB;IAAmB,gBACxCpB,KAAA,CAAAa,aAAA;MAAKM,SAAS,EAAEJ;IAAiB,GAAET,QAAc,CAC9C,CAAC;EAEV;EAEA,oBACEN,KAAA,CAAAa,aAAA,CAAChB,WAAW,CAACwB,IAAI;IACf;IACAC,WAAW,EAAE,CAACb,kBAAmB;IACjCU,SAAS,EAAEjB,MAAM,CAACkB;EAAmB,gBAErCpB,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEjB,MAAM,CAACqB;EAAsB,gBAC3CvB,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEjB,MAAM,CAACsB;EAAyB,gBAC9CxB,KAAA,CAAAa,aAAA;IAAMM,SAAS,EAAEjB,MAAM,CAACuB;EAAqB,GAAElB,KAAY,CAAC,EAC3DC,WAAW,IAAI,IAAI,iBAClBR,KAAA,CAAAa,aAAA;IAAMM,SAAS,EAAEjB,MAAM,CAACwB;EAA2B,GAChDlB,WACG,CAEL,CAAC,eACNR,KAAA,CAAAa,aAAA,CAAChB,WAAW,CAAC8B,OAAO;IAClBR,SAAS,EAAEjB,MAAM,CAAC0B,sBAAuB;IACzC,cAAYrB;EAAM,GAEjBF,UAAU,GAAG,CAAC,iBACbL,KAAA,CAAAa,aAAA;IAAMM,SAAS,EAAEjB,MAAM,CAAC2B,yBAA0B;IAACC,IAAI,EAAC;EAAQ,GAC7DzB,UAAU,KAAK,CAAC,GAAG,SAAS,GAAG,GAAGA,UAAU,SACzC,CACP,eACDL,KAAA,CAAAa,aAAA;IAAMM,SAAS,EAAEjB,MAAM,CAAC6B;EAAuB,gBAC7C/B,KAAA,CAAAa,aAAA,CAACf,SAAS;IAACkC,IAAI,EAAE;EAAG,CAAE,CAClB,CACa,CAClB,CAAC,eAENhC,KAAA,CAAAa,aAAA,CAAChB,WAAW,CAACoC,KAAK;IAACC,WAAW,EAAE;EAAK,gBACnClC,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEJ;EAAiB,GAAET,QAAc,CAChC,CACH,CAAC;AAEvB,CACF,CAAC;AAQD,MAAMQ,cAAc,gBAAGb,IAAI,CAAC,UAA0B;EACpDM,KAAK;EACLC,WAAW;EACXF;AACmB,CAAC,EAAsB;EAC1C,oBACEN,KAAA,CAAAa,aAAA,2BACEb,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEjB,MAAM,CAACiC;EAA6B,gBAClDnC,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEjB,MAAM,CAACkC;EAA4B,GAAE7B,KAAW,CAAC,EAChEC,WAAW,IAAI,IAAI,iBAClBR,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEjB,MAAM,CAACmC;EAAkC,GACtD7B,WACE,CAEJ,CAAC,eACNR,KAAA,CAAAa,aAAA;IAAKM,SAAS,EAAEjB,MAAM,CAACoC;EAA8B,GAAEhC,QAAc,CAClE,CAAC;AAEV,CAAC,CAAC","ignoreList":[]}