@osdk/react-components 0.2.0 → 0.3.0-main-20260407112212

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 (40) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/build/browser/action-form/FormFieldApi.js.map +1 -1
  3. package/build/browser/action-form/fields/FilePickerField.js +119 -0
  4. package/build/browser/action-form/fields/FilePickerField.js.map +1 -0
  5. package/build/browser/action-form/fields/FilePickerField.module.css +132 -0
  6. package/build/browser/action-form/fields/FilePickerField.module.css.js +11 -0
  7. package/build/browser/action-form/fields/FormFieldRenderer.js +20 -0
  8. package/build/browser/action-form/fields/FormFieldRenderer.js.map +1 -1
  9. package/build/browser/object-table/ObjectTableApi.js.map +1 -1
  10. package/build/browser/object-table/hooks/useFunctionColumnsData.js +13 -3
  11. package/build/browser/object-table/hooks/useFunctionColumnsData.js.map +1 -1
  12. package/build/browser/object-table/hooks/useObjectTableData.js.map +1 -1
  13. package/build/browser/styles.css +135 -0
  14. package/build/cjs/public/experimental.cjs +125 -4
  15. package/build/cjs/public/experimental.cjs.map +1 -1
  16. package/build/cjs/public/experimental.css +94 -0
  17. package/build/cjs/public/experimental.css.map +1 -1
  18. package/build/cjs/public/experimental.d.cts +19 -1
  19. package/build/esm/action-form/FormFieldApi.js.map +1 -1
  20. package/build/esm/action-form/fields/FilePickerField.js +119 -0
  21. package/build/esm/action-form/fields/FilePickerField.js.map +1 -0
  22. package/build/esm/action-form/fields/FilePickerField.module.css +132 -0
  23. package/build/esm/action-form/fields/FormFieldRenderer.js +20 -0
  24. package/build/esm/action-form/fields/FormFieldRenderer.js.map +1 -1
  25. package/build/esm/object-table/ObjectTableApi.js.map +1 -1
  26. package/build/esm/object-table/hooks/useFunctionColumnsData.js +13 -3
  27. package/build/esm/object-table/hooks/useFunctionColumnsData.js.map +1 -1
  28. package/build/esm/object-table/hooks/useObjectTableData.js.map +1 -1
  29. package/build/types/action-form/FormFieldApi.d.ts +12 -0
  30. package/build/types/action-form/FormFieldApi.d.ts.map +1 -1
  31. package/build/types/action-form/fields/FilePickerField.d.ts +3 -0
  32. package/build/types/action-form/fields/FilePickerField.d.ts.map +1 -0
  33. package/build/types/action-form/fields/FormFieldRenderer.d.ts.map +1 -1
  34. package/build/types/object-table/ObjectTableApi.d.ts +7 -1
  35. package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
  36. package/build/types/object-table/hooks/useFunctionColumnsData.d.ts +1 -0
  37. package/build/types/object-table/hooks/useFunctionColumnsData.d.ts.map +1 -1
  38. package/build/types/object-table/hooks/useObjectTableData.d.ts +1 -3
  39. package/build/types/object-table/hooks/useObjectTableData.d.ts.map +1 -1
  40. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"useFunctionColumnsData.js","names":["useOsdkFunctions","useMemo","createAsyncCellData","useFunctionColumnsData","objectSet","objects","columnDefinitions","functionColumnConfigs","getFunctionColumnConfigs","stableObjects","useStableObjects","stableObjectSet","JSON","stringify","disabled","length","queries","map","config","queryDefinition","options","params","getParams","results","enabled","data","columnData","forEach","result","index","functionsMap","columnIds","columnId","getValue","getKey","columnGetKey","obj","key","String","$primaryKey","isLoading","error","customKey","rawData","cellData","configsByApiName","Map","colDef","locator","type","apiName","existingConfig","get","push","id","set","getFunctionParams","Array","from","values","item","$apiName","sort","a","b","localeCompare"],"sources":["useFunctionColumnsData.ts"],"sourcesContent":["/*\n * Copyright 2026 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 ObjectOrInterfaceDefinition,\n ObjectSet,\n Osdk,\n PropertyKeys,\n QueryDefinition,\n SimplePropertyDef,\n} from \"@osdk/api\";\nimport {\n type FunctionQueryParams,\n useOsdkFunctions,\n} from \"@osdk/react/unstable-do-not-use\";\n\nimport { useMemo } from \"react\";\nimport type {\n ColumnDefinition,\n FunctionColumnLocator,\n} from \"../ObjectTableApi.js\";\nimport {\n type AsyncCellData,\n createAsyncCellData,\n} from \"../utils/AsyncCellData.js\";\n\nexport interface FunctionColumnData {\n [columnId: string]: {\n [objectPrimaryKey: string]: AsyncCellData;\n };\n}\n\ntype FunctionColumnConfig<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n> = {\n queryDefinition: QueryDefinition<unknown>;\n getParams: (\n objectSet: ObjectSet<Q, RDPs>,\n ) => unknown;\n columnIds: Array<{\n columnId: string;\n getValue?: (cellData: unknown) => unknown;\n getKey: (\n object: Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>,\n ) => string;\n }>;\n};\n\nexport function useFunctionColumnsData<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectSet: ObjectSet<Q, RDPs> | undefined,\n objects:\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n): FunctionColumnData {\n // Function column configurations grouped by unique query definition\n const functionColumnConfigs = useMemo(\n () => getFunctionColumnConfigs(columnDefinitions),\n [columnDefinitions],\n );\n\n const stableObjects = useStableObjects(objects);\n\n // TODO: replace with useDeepEqual when it's added\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const stableObjectSet = useMemo(() => objectSet, [JSON.stringify(objectSet)]);\n\n const disabled = !stableObjectSet || !stableObjects?.length\n || functionColumnConfigs.length === 0;\n\n // Prepare queries for useOsdkFunctions\n const queries = useMemo(\n () => {\n if (disabled) {\n return [];\n }\n\n return functionColumnConfigs.map(\n (config): FunctionQueryParams<QueryDefinition<unknown>> => ({\n queryDefinition: config.queryDefinition,\n options: {\n params: config.getParams(stableObjectSet),\n } as FunctionQueryParams<QueryDefinition<unknown>>[\"options\"],\n }),\n );\n },\n [disabled, functionColumnConfigs, stableObjectSet],\n );\n\n const results = useOsdkFunctions(\n {\n queries,\n enabled: !disabled,\n },\n );\n\n const data = useMemo(() => {\n const columnData: FunctionColumnData = {};\n\n if (disabled || !stableObjects) return columnData;\n\n results.forEach((result, index) => {\n const config = functionColumnConfigs[index];\n if (!config) return;\n\n const functionsMap = result.data as Record<string, unknown> | undefined;\n\n config.columnIds.forEach(\n ({ columnId, getValue, getKey: columnGetKey }) => {\n if (!columnData[columnId]) {\n columnData[columnId] = {};\n }\n\n stableObjects.forEach(obj => {\n const key = String(obj.$primaryKey);\n\n if (result.isLoading) {\n columnData[columnId][key] = createAsyncCellData({\n isLoading: true,\n });\n } else if (result.error) {\n columnData[columnId][key] = createAsyncCellData({\n error: result.error,\n isLoading: false,\n });\n } else if (functionsMap) {\n const customKey = columnGetKey(obj);\n const rawData = functionsMap[customKey];\n const cellData = getValue ? getValue(rawData) : rawData;\n columnData[columnId][key] = createAsyncCellData({\n data: cellData,\n isLoading: false,\n });\n }\n });\n },\n );\n });\n\n return columnData;\n }, [results, functionColumnConfigs, stableObjects, disabled]);\n\n return data;\n}\n\nfunction getFunctionColumnConfigs<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n): Array<FunctionColumnConfig<Q, RDPs>> {\n if (!columnDefinitions) return [];\n\n // Group columns by their query definition apiName\n const configsByApiName = new Map<\n string,\n FunctionColumnConfig<Q, RDPs>\n >();\n\n columnDefinitions.forEach((colDef) => {\n if (colDef.locator.type === \"function\") {\n const locator = colDef.locator as FunctionColumnLocator<\n Q,\n RDPs,\n FunctionColumns\n >;\n\n const apiName = locator.queryDefinition.apiName;\n const existingConfig = configsByApiName.get(apiName);\n\n if (existingConfig) {\n // Add this column to the existing config\n existingConfig.columnIds.push({\n columnId: String(locator.id),\n getValue: locator.getValue,\n getKey: locator.getKey,\n });\n } else {\n // Create new config\n configsByApiName.set(apiName, {\n queryDefinition: locator.queryDefinition,\n getParams: locator.getFunctionParams,\n columnIds: [{\n columnId: String(locator.id),\n getValue: locator.getValue,\n getKey: locator.getKey,\n }],\n });\n }\n }\n });\n\n return Array.from(configsByApiName.values());\n}\n\nconst useStableObjects = <\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n>(\n objects:\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined,\n):\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined =>\n{\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => objects, [\n // eslint-disable-next-line react-hooks/exhaustive-deps\n JSON.stringify(\n (objects ?? []).map(item => ({\n $apiName: item.$apiName,\n $primaryKey: item.$primaryKey,\n })).sort((a, b) => {\n if (a.$apiName !== b.$apiName) {\n return a.$apiName.localeCompare(b.$apiName);\n }\n return String(a.$primaryKey).localeCompare(String(b.$primaryKey));\n }),\n ),\n ]);\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"useFunctionColumnsData.js","names":["useOsdkFunctions","useMemo","createAsyncCellData","DEFAULT_DEDUPE_INTERVAL_MS","useFunctionColumnsData","objectSet","objects","columnDefinitions","functionColumnConfigs","getFunctionColumnConfigs","stableObjects","useStableObjects","stableObjectSet","JSON","stringify","disabled","length","queries","map","config","queryDefinition","options","params","getParams","dedupeIntervalMs","results","enabled","data","columnData","forEach","result","index","functionsMap","columnIds","columnId","getValue","getKey","columnGetKey","obj","key","String","$primaryKey","isLoading","error","customKey","rawData","cellData","configsByApiName","Map","colDef","locator","type","apiName","existingConfig","get","push","id","Math","min","set","getFunctionParams","Array","from","values","item","$apiName","sort","a","b","localeCompare"],"sources":["useFunctionColumnsData.ts"],"sourcesContent":["/*\n * Copyright 2026 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 ObjectOrInterfaceDefinition,\n ObjectSet,\n Osdk,\n PropertyKeys,\n QueryDefinition,\n SimplePropertyDef,\n} from \"@osdk/api\";\nimport {\n type FunctionQueryParams,\n useOsdkFunctions,\n} from \"@osdk/react/experimental\";\n\nimport { useMemo } from \"react\";\nimport type {\n ColumnDefinition,\n FunctionColumnLocator,\n} from \"../ObjectTableApi.js\";\nimport {\n type AsyncCellData,\n createAsyncCellData,\n} from \"../utils/AsyncCellData.js\";\n\nexport interface FunctionColumnData {\n [columnId: string]: {\n [objectPrimaryKey: string]: AsyncCellData;\n };\n}\n\ntype FunctionColumnConfig<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n> = {\n queryDefinition: QueryDefinition<unknown>;\n getParams: (\n objectSet: ObjectSet<Q, RDPs>,\n ) => unknown;\n columnIds: Array<{\n columnId: string;\n getValue?: (cellData: unknown) => unknown;\n getKey: (\n object: Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>,\n ) => string;\n }>;\n dedupeIntervalMs?: number;\n};\n\n// Function column data is readOnly and can be cached aggressively,\n// so we set a longer dedupe interval to maximize cache hits\nexport const DEFAULT_DEDUPE_INTERVAL_MS = 300_000; // 5 minutes\n\nexport function useFunctionColumnsData<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectSet: ObjectSet<Q, RDPs> | undefined,\n objects:\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n): FunctionColumnData {\n // Function column configurations grouped by unique query definition\n const functionColumnConfigs = useMemo(\n () => getFunctionColumnConfigs(columnDefinitions),\n [columnDefinitions],\n );\n\n const stableObjects = useStableObjects(objects);\n\n // TODO: replace with useDeepEqual when it's added\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const stableObjectSet = useMemo(() => objectSet, [JSON.stringify(objectSet)]);\n\n const disabled = !stableObjectSet || !stableObjects?.length\n || functionColumnConfigs.length === 0;\n\n // Prepare queries for useOsdkFunctions\n const queries = useMemo(\n () => {\n if (disabled) {\n return [];\n }\n\n return functionColumnConfigs.map(\n (config): FunctionQueryParams<QueryDefinition<unknown>> => ({\n queryDefinition: config.queryDefinition,\n options: {\n params: config.getParams(stableObjectSet),\n dedupeIntervalMs: config.dedupeIntervalMs\n ?? DEFAULT_DEDUPE_INTERVAL_MS,\n } as FunctionQueryParams<QueryDefinition<unknown>>[\"options\"],\n }),\n );\n },\n [disabled, functionColumnConfigs, stableObjectSet],\n );\n\n const results = useOsdkFunctions(\n {\n queries,\n enabled: !disabled,\n },\n );\n\n const data = useMemo(() => {\n const columnData: FunctionColumnData = {};\n\n if (disabled || !stableObjects) return columnData;\n\n results.forEach((result, index) => {\n const config = functionColumnConfigs[index];\n if (!config) return;\n\n const functionsMap = result.data as Record<string, unknown> | undefined;\n\n config.columnIds.forEach(\n ({ columnId, getValue, getKey: columnGetKey }) => {\n if (!columnData[columnId]) {\n columnData[columnId] = {};\n }\n\n stableObjects.forEach(obj => {\n const key = String(obj.$primaryKey);\n\n if (result.isLoading) {\n columnData[columnId][key] = createAsyncCellData({\n isLoading: true,\n });\n } else if (result.error) {\n columnData[columnId][key] = createAsyncCellData({\n error: result.error,\n isLoading: false,\n });\n } else if (functionsMap) {\n const customKey = columnGetKey(obj);\n const rawData = functionsMap[customKey];\n const cellData = getValue ? getValue(rawData) : rawData;\n columnData[columnId][key] = createAsyncCellData({\n data: cellData,\n isLoading: false,\n });\n }\n });\n },\n );\n });\n\n return columnData;\n }, [results, functionColumnConfigs, stableObjects, disabled]);\n\n return data;\n}\n\nfunction getFunctionColumnConfigs<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n): Array<FunctionColumnConfig<Q, RDPs>> {\n if (!columnDefinitions) return [];\n\n // Group columns by their query definition apiName\n const configsByApiName = new Map<\n string,\n FunctionColumnConfig<Q, RDPs>\n >();\n\n columnDefinitions.forEach((colDef) => {\n if (colDef.locator.type === \"function\") {\n const locator = colDef.locator as FunctionColumnLocator<\n Q,\n RDPs,\n FunctionColumns\n >;\n\n const apiName = locator.queryDefinition.apiName;\n const existingConfig = configsByApiName.get(apiName);\n\n if (existingConfig) {\n // Add this column to the existing config\n existingConfig.columnIds.push({\n columnId: String(locator.id),\n getValue: locator.getValue,\n getKey: locator.getKey,\n });\n // When multiple columns share a query, use the shortest dedupe interval\n if (locator.dedupeIntervalMs != null) {\n existingConfig.dedupeIntervalMs = existingConfig.dedupeIntervalMs\n != null\n ? Math.min(\n existingConfig.dedupeIntervalMs,\n locator.dedupeIntervalMs,\n )\n : locator.dedupeIntervalMs;\n }\n } else {\n // Create new config\n configsByApiName.set(apiName, {\n queryDefinition: locator.queryDefinition,\n getParams: locator.getFunctionParams,\n columnIds: [{\n columnId: String(locator.id),\n getValue: locator.getValue,\n getKey: locator.getKey,\n }],\n dedupeIntervalMs: locator.dedupeIntervalMs,\n });\n }\n }\n });\n\n return Array.from(configsByApiName.values());\n}\n\nconst useStableObjects = <\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n>(\n objects:\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined,\n):\n | Osdk.Instance<Q, \"$allBaseProperties\", PropertyKeys<Q>, RDPs>[]\n | undefined =>\n{\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => objects, [\n // eslint-disable-next-line react-hooks/exhaustive-deps\n JSON.stringify(\n (objects ?? []).map(item => ({\n $apiName: item.$apiName,\n $primaryKey: item.$primaryKey,\n })).sort((a, b) => {\n if (a.$apiName !== b.$apiName) {\n return a.$apiName.localeCompare(b.$apiName);\n }\n return String(a.$primaryKey).localeCompare(String(b.$primaryKey));\n }),\n ),\n ]);\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"useObjectTableData.js","names":["useObjectSet","useOsdkObjects","useMemo","useFunctionColumnsData","PAGE_SIZE","useObjectTableData","objectOrInterfaceType","columnDefinitions","filter","sorting","objectSet","objectSetOptions","orderBy","length","undefined","reduce","acc","sort","id","desc","withProperties","rdpColumns","map","colDef","locator","colLocator","type","cur","creator","isObjectType","shouldUseObjectSet","objectSetResult","where","pageSize","enabled","osdkObjectsResult","baseResult","functionColumnData","data","mergedData","obj","objKey","String","$primaryKey","functionData","Object","entries","forEach","columnId","columnData"],"sources":["useObjectTableData.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 DerivedProperty,\n ObjectOrInterfaceDefinition,\n ObjectSet,\n PropertyKeys,\n QueryDefinition,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\nimport type { UseOsdkListResult } from \"@osdk/react/experimental\";\nimport { useObjectSet, useOsdkObjects } from \"@osdk/react/experimental\";\nimport type { SortingState } from \"@tanstack/react-table\";\nimport { useMemo } from \"react\";\nimport type { ColumnDefinition, ObjectSetOptions } from \"../ObjectTableApi.js\";\nimport type { AsyncCellData } from \"../utils/AsyncCellData.js\";\nimport { useFunctionColumnsData } from \"./useFunctionColumnsData.js\";\n\nconst PAGE_SIZE = 50;\n\ntype WithProperties<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n> = {\n [K in keyof RDPs]: DerivedProperty.Creator<Q, RDPs[K]>;\n};\n\ninterface UseObjectTableDataResult<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n> extends Omit<UseOsdkListResult<Q, RDPs>, \"isOptimistic\"> {\n objectSet?: ObjectSet<Q>;\n}\n/**\n * This hook is a wrapper that conditionally uses either useObjectSet or useOsdkObjects\n * based on whether an objectSet prop is provided.\n * It extracts RDP locators from columnDefinitions and applies withProperties\n * to return data containing the derived properties.\n */\nexport function useObjectTableData<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectOrInterfaceType: Q,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n filter?: WhereClause<Q, RDPs>,\n sorting?: SortingState,\n objectSet?: ObjectSet<Q>,\n objectSetOptions?: ObjectSetOptions<Q>,\n): UseObjectTableDataResult<Q, RDPs> {\n const orderBy = useMemo(() => {\n if (!sorting || sorting.length === 0) {\n return undefined;\n }\n\n return sorting.reduce<{ [K in PropertyKeys<Q>]?: \"asc\" | \"desc\" }>(\n (acc, sort) => {\n acc[sort.id as PropertyKeys<Q>] = sort.desc ? \"desc\" : \"asc\";\n return acc;\n },\n {},\n );\n }, [sorting]);\n\n // Extract derived properties definition\n const withProperties = useMemo(() => {\n if (!columnDefinitions) {\n return;\n }\n\n const rdpColumns = columnDefinitions.map(colDef => colDef.locator).filter(\n (colLocator) => {\n return colLocator.type === \"rdp\";\n },\n );\n\n if (!rdpColumns.length) {\n return;\n }\n\n return rdpColumns.reduce<WithProperties<Q, RDPs>>(\n (acc, cur) => {\n return {\n ...acc,\n [cur.id]: cur.creator,\n };\n },\n {} as WithProperties<Q, RDPs>,\n );\n }, [columnDefinitions]);\n\n // When objectSet is provided and it's an object type, use useObjectSet. Otherwise, use useOsdkObjects.\n const isObjectType = objectOrInterfaceType.type === \"object\";\n const shouldUseObjectSet = !!objectSet && isObjectType;\n\n // When shouldUseObjectSet is true, we know objectSet is defined\n // and objectOrInterfaceType is an ObjectTypeDefinition\n const objectSetResult = useObjectSet(\n shouldUseObjectSet ? objectSet as ObjectSet<Q, RDPs> : undefined as any,\n {\n ...(objectSetOptions as ObjectSetOptions<Q>),\n withProperties: withProperties as WithProperties<\n Q,\n RDPs\n >,\n where: filter,\n orderBy,\n pageSize: PAGE_SIZE,\n enabled: shouldUseObjectSet,\n },\n );\n\n const osdkObjectsResult = useOsdkObjects<\n Q,\n RDPs\n >(\n objectOrInterfaceType,\n {\n withProperties,\n pageSize: PAGE_SIZE,\n where: filter,\n orderBy,\n enabled: !shouldUseObjectSet,\n },\n );\n\n // Get the result from the appropriate hook\n const baseResult = shouldUseObjectSet ? objectSetResult : osdkObjectsResult;\n\n // Call useFunctionColumnsData to get function column data\n const functionColumnData = useFunctionColumnsData<Q, RDPs, FunctionColumns>(\n objectSetResult.objectSet,\n baseResult.data,\n columnDefinitions,\n );\n\n // Merge function column data into each object\n const mergedData = useMemo(() => {\n if (!baseResult.data) return baseResult.data;\n\n return baseResult.data.map(obj => {\n const objKey = String(obj.$primaryKey);\n const functionData: Record<string, AsyncCellData> = {};\n\n // Collect all function column data for this object\n Object.entries(functionColumnData).forEach(([columnId, columnData]) => {\n if (columnData[objKey]) {\n functionData[columnId] = columnData[objKey];\n }\n });\n\n // Return object with function data merged in\n return {\n ...obj,\n ...functionData,\n };\n });\n }, [baseResult.data, functionColumnData]);\n\n // Return the result with merged data\n return {\n ...baseResult,\n data: mergedData,\n } as UseObjectTableDataResult<Q, RDPs>;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"useObjectTableData.js","names":["useObjectSet","useOsdkObjects","useMemo","useFunctionColumnsData","PAGE_SIZE","useObjectTableData","objectOrInterfaceType","columnDefinitions","filter","sorting","objectSet","objectSetOptions","orderBy","length","undefined","reduce","acc","sort","id","desc","withProperties","rdpColumns","map","colDef","locator","colLocator","type","cur","creator","isObjectType","shouldUseObjectSet","objectSetResult","where","pageSize","enabled","osdkObjectsResult","baseResult","functionColumnData","data","mergedData","obj","objKey","String","$primaryKey","functionData","Object","entries","forEach","columnId","columnData"],"sources":["useObjectTableData.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 DerivedProperty,\n ObjectOrInterfaceDefinition,\n ObjectSet,\n PropertyKeys,\n QueryDefinition,\n SimplePropertyDef,\n WhereClause,\n} from \"@osdk/api\";\nimport type { UseOsdkListResult } from \"@osdk/react/experimental\";\nimport { useObjectSet, useOsdkObjects } from \"@osdk/react/experimental\";\nimport type { SortingState } from \"@tanstack/react-table\";\nimport { useMemo } from \"react\";\nimport type { ColumnDefinition, ObjectSetOptions } from \"../ObjectTableApi.js\";\nimport type { AsyncCellData } from \"../utils/AsyncCellData.js\";\nimport { useFunctionColumnsData } from \"./useFunctionColumnsData.js\";\n\nconst PAGE_SIZE = 50;\n\ntype WithProperties<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n> = {\n [K in keyof RDPs]: DerivedProperty.Creator<Q, RDPs[K]>;\n};\n\ninterface UseObjectTableDataResult<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<string, never>,\n> extends Omit<UseOsdkListResult<Q, RDPs>, \"isOptimistic\"> {}\n/**\n * This hook is a wrapper that conditionally uses either useObjectSet or useOsdkObjects\n * based on whether an objectSet prop is provided.\n * It extracts RDP locators from columnDefinitions and applies withProperties\n * to return data containing the derived properties.\n */\nexport function useObjectTableData<\n Q extends ObjectOrInterfaceDefinition,\n RDPs extends Record<string, SimplePropertyDef> = Record<\n string,\n never\n >,\n FunctionColumns extends Record<string, QueryDefinition<{}>> = Record<\n string,\n never\n >,\n>(\n objectOrInterfaceType: Q,\n columnDefinitions?: Array<ColumnDefinition<Q, RDPs, FunctionColumns>>,\n filter?: WhereClause<Q, RDPs>,\n sorting?: SortingState,\n objectSet?: ObjectSet<Q>,\n objectSetOptions?: ObjectSetOptions<Q>,\n): UseObjectTableDataResult<Q, RDPs> {\n const orderBy = useMemo(() => {\n if (!sorting || sorting.length === 0) {\n return undefined;\n }\n\n return sorting.reduce<{ [K in PropertyKeys<Q>]?: \"asc\" | \"desc\" }>(\n (acc, sort) => {\n acc[sort.id as PropertyKeys<Q>] = sort.desc ? \"desc\" : \"asc\";\n return acc;\n },\n {},\n );\n }, [sorting]);\n\n // Extract derived properties definition\n const withProperties = useMemo(() => {\n if (!columnDefinitions) {\n return;\n }\n\n const rdpColumns = columnDefinitions.map(colDef => colDef.locator).filter(\n (colLocator) => {\n return colLocator.type === \"rdp\";\n },\n );\n\n if (!rdpColumns.length) {\n return;\n }\n\n return rdpColumns.reduce<WithProperties<Q, RDPs>>(\n (acc, cur) => {\n return {\n ...acc,\n [cur.id]: cur.creator,\n };\n },\n {} as WithProperties<Q, RDPs>,\n );\n }, [columnDefinitions]);\n\n // When objectSet is provided and it's an object type, use useObjectSet. Otherwise, use useOsdkObjects.\n const isObjectType = objectOrInterfaceType.type === \"object\";\n const shouldUseObjectSet = !!objectSet && isObjectType;\n\n // When shouldUseObjectSet is true, we know objectSet is defined\n // and objectOrInterfaceType is an ObjectTypeDefinition\n const objectSetResult = useObjectSet(\n shouldUseObjectSet ? objectSet as ObjectSet<Q, RDPs> : undefined as any,\n {\n ...(objectSetOptions as ObjectSetOptions<Q>),\n withProperties: withProperties as WithProperties<\n Q,\n RDPs\n >,\n where: filter,\n orderBy,\n pageSize: PAGE_SIZE,\n enabled: shouldUseObjectSet,\n },\n );\n\n const osdkObjectsResult = useOsdkObjects<\n Q,\n RDPs\n >(\n objectOrInterfaceType,\n {\n withProperties,\n pageSize: PAGE_SIZE,\n where: filter,\n orderBy,\n enabled: !shouldUseObjectSet,\n },\n );\n\n // Get the result from the appropriate hook\n const baseResult = shouldUseObjectSet ? objectSetResult : osdkObjectsResult;\n\n // Call useFunctionColumnsData to get function column data\n const functionColumnData = useFunctionColumnsData<Q, RDPs, FunctionColumns>(\n objectSetResult.objectSet,\n baseResult.data,\n columnDefinitions,\n );\n\n // Merge function column data into each object\n const mergedData = useMemo(() => {\n if (!baseResult.data) return baseResult.data;\n\n return baseResult.data.map(obj => {\n const objKey = String(obj.$primaryKey);\n const functionData: Record<string, AsyncCellData> = {};\n\n // Collect all function column data for this object\n Object.entries(functionColumnData).forEach(([columnId, columnData]) => {\n if (columnData[objKey]) {\n functionData[columnId] = columnData[objKey];\n }\n });\n\n // Return object with function data merged in\n return {\n ...obj,\n ...functionData,\n };\n });\n }, [baseResult.data, functionColumnData]);\n\n // Return the result with merged data\n return {\n ...baseResult,\n data: mergedData,\n } as UseObjectTableDataResult<Q, RDPs>;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -381,6 +381,141 @@
381
381
  }
382
382
 
383
383
 
384
+ /* action-form/fields/FilePickerField.module.css */
385
+ /*
386
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
387
+ *
388
+ * Licensed under the Apache License, Version 2.0 (the "License");
389
+ * you may not use this file except in compliance with the License.
390
+ * You may obtain a copy of the License at
391
+ *
392
+ * http://www.apache.org/licenses/LICENSE-2.0
393
+ *
394
+ * Unless required by applicable law or agreed to in writing, software
395
+ * distributed under the License is distributed on an "AS IS" BASIS,
396
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
397
+ * See the License for the specific language governing permissions and
398
+ * limitations under the License.
399
+ */
400
+
401
+ /* Outer wrapper — looks like an input field */
402
+ .FilePickerField-module__osdkFilePickerTrigger___xiODCPnX {
403
+ display: flex;
404
+ align-items: center;
405
+ width: 100%;
406
+ height: var(--osdk-file-picker-trigger-min-height);
407
+ border: var(--osdk-file-picker-trigger-border);
408
+ border-radius: var(--osdk-file-picker-trigger-border-radius);
409
+ background: var(--osdk-file-picker-trigger-bg);
410
+ font-family: var(--osdk-file-picker-trigger-font-family);
411
+ font-size: var(--osdk-file-picker-trigger-font-size);
412
+ box-sizing: border-box;
413
+ overflow: hidden;
414
+ transition:
415
+ background-color var(--osdk-file-picker-transition-duration)
416
+ var(--osdk-file-picker-transition-ease),
417
+ border-color var(--osdk-file-picker-transition-duration)
418
+ var(--osdk-file-picker-transition-ease);
419
+
420
+ &:hover {
421
+ background: var(--osdk-file-picker-trigger-bg-hover);
422
+ }
423
+
424
+ &:focus-visible {
425
+ border-color: var(--osdk-file-picker-trigger-border-color-focus);
426
+ outline: var(--osdk-file-picker-trigger-focus-width) solid
427
+ var(--osdk-file-picker-trigger-focus-color);
428
+ outline-offset: var(--osdk-file-picker-trigger-focus-offset);
429
+ }
430
+ }
431
+
432
+ /* Visually hidden file input */
433
+ .FilePickerField-module__osdkFilePickerHiddenInput___HiJGgrUM {
434
+ position: absolute;
435
+ width: 1px;
436
+ height: 1px;
437
+ padding: 0;
438
+ margin: -1px;
439
+ overflow: hidden;
440
+ clip: rect(0, 0, 0, 0);
441
+ white-space: nowrap;
442
+ border: 0;
443
+ }
444
+
445
+ /* File name text (left section) */
446
+ .FilePickerField-module__osdkFilePickerText___VbLe9-Bb {
447
+ flex: 1;
448
+ padding: var(--osdk-file-picker-trigger-padding);
449
+ overflow: hidden;
450
+ text-overflow: ellipsis;
451
+ white-space: nowrap;
452
+ text-align: left;
453
+ color: var(--osdk-file-picker-trigger-color);
454
+ cursor: pointer;
455
+ background: none;
456
+ border: none;
457
+ font-family: inherit;
458
+ font-size: inherit;
459
+ }
460
+
461
+ .FilePickerField-module__osdkFilePickerPlaceholder___ntQ09iNR {
462
+ color: var(--osdk-file-picker-trigger-placeholder-color);
463
+ }
464
+
465
+ /* Clear ✕ button */
466
+ .FilePickerField-module__osdkFilePickerClear___SOf8mcYq {
467
+ display: flex;
468
+ align-items: center;
469
+ justify-content: center;
470
+ flex-shrink: 0;
471
+ width: var(--osdk-file-picker-clear-size);
472
+ height: var(--osdk-file-picker-clear-size);
473
+ margin: var(--osdk-file-picker-clear-margin);
474
+ padding: 0;
475
+ border: none;
476
+ background: none;
477
+ color: var(--osdk-file-picker-clear-color);
478
+ cursor: pointer;
479
+ transition: color var(--osdk-file-picker-transition-duration)
480
+ var(--osdk-file-picker-transition-ease);
481
+
482
+ &:hover {
483
+ color: var(--osdk-file-picker-clear-color-hover);
484
+ }
485
+
486
+ &:focus-visible {
487
+ outline: var(--osdk-file-picker-trigger-focus-width) solid
488
+ var(--osdk-file-picker-trigger-focus-color);
489
+ border-radius: var(--osdk-surface-border-radius);
490
+ }
491
+ }
492
+
493
+ /* Browse label (right section) */
494
+ .FilePickerField-module__osdkFilePickerBrowse___XurnxfvY {
495
+ flex-shrink: 0;
496
+ align-self: stretch;
497
+ display: flex;
498
+ align-items: center;
499
+ padding: var(--osdk-file-picker-browse-padding);
500
+ border-left: var(--osdk-file-picker-browse-border-left);
501
+ background: var(--osdk-file-picker-browse-bg);
502
+ color: var(--osdk-file-picker-browse-color);
503
+ font-family: var(--osdk-file-picker-trigger-font-family);
504
+ font-size: var(--osdk-file-picker-trigger-font-size);
505
+ pointer-events: none;
506
+ transition: background-color var(--osdk-file-picker-transition-duration)
507
+ var(--osdk-file-picker-transition-ease);
508
+ }
509
+
510
+ .FilePickerField-module__osdkFilePickerTrigger___xiODCPnX:hover .FilePickerField-module__osdkFilePickerBrowse___XurnxfvY {
511
+ background-color: var(--osdk-file-picker-browse-bg-hover);
512
+ }
513
+
514
+ .FilePickerField-module__osdkFilePickerTrigger___xiODCPnX:active .FilePickerField-module__osdkFilePickerBrowse___XurnxfvY {
515
+ background-color: var(--osdk-file-picker-browse-bg-active);
516
+ }
517
+
518
+
384
519
  /* action-form/fields/NumberInputField.module.css */
385
520
  /*
386
521
  * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
@@ -19,7 +19,6 @@ var checkbox = require('@base-ui/react/checkbox');
19
19
  var combobox = require('@base-ui/react/combobox');
20
20
  var react = require('@osdk/react');
21
21
  var reactTable = require('@tanstack/react-table');
22
- var unstableDoNotUse = require('@osdk/react/unstable-do-not-use');
23
22
  var collapsible = require('@base-ui/react/collapsible');
24
23
  var reactVirtual = require('@tanstack/react-virtual');
25
24
  var reactDom = require('react-dom');
@@ -4667,6 +4666,7 @@ function useEditableTable({
4667
4666
  clearCellValidationError
4668
4667
  };
4669
4668
  }
4669
+ var DEFAULT_DEDUPE_INTERVAL_MS = 3e5;
4670
4670
  function useFunctionColumnsData(objectSet, objects, columnDefinitions) {
4671
4671
  const functionColumnConfigs = React76.useMemo(() => getFunctionColumnConfigs(columnDefinitions), [columnDefinitions]);
4672
4672
  const stableObjects = useStableObjects(objects);
@@ -4679,11 +4679,12 @@ function useFunctionColumnsData(objectSet, objects, columnDefinitions) {
4679
4679
  return functionColumnConfigs.map((config) => ({
4680
4680
  queryDefinition: config.queryDefinition,
4681
4681
  options: {
4682
- params: config.getParams(stableObjectSet)
4682
+ params: config.getParams(stableObjectSet),
4683
+ dedupeIntervalMs: config.dedupeIntervalMs ?? DEFAULT_DEDUPE_INTERVAL_MS
4683
4684
  }
4684
4685
  }));
4685
4686
  }, [disabled, functionColumnConfigs, stableObjectSet]);
4686
- const results = unstableDoNotUse.useOsdkFunctions({
4687
+ const results = experimental.useOsdkFunctions({
4687
4688
  queries,
4688
4689
  enabled: !disabled
4689
4690
  });
@@ -4743,6 +4744,9 @@ function getFunctionColumnConfigs(columnDefinitions) {
4743
4744
  getValue: locator.getValue,
4744
4745
  getKey: locator.getKey
4745
4746
  });
4747
+ if (locator.dedupeIntervalMs != null) {
4748
+ existingConfig.dedupeIntervalMs = existingConfig.dedupeIntervalMs != null ? Math.min(existingConfig.dedupeIntervalMs, locator.dedupeIntervalMs) : locator.dedupeIntervalMs;
4749
+ }
4746
4750
  } else {
4747
4751
  configsByApiName.set(apiName, {
4748
4752
  queryDefinition: locator.queryDefinition,
@@ -4751,7 +4755,8 @@ function getFunctionColumnConfigs(columnDefinitions) {
4751
4755
  columnId: String(locator.id),
4752
4756
  getValue: locator.getValue,
4753
4757
  getKey: locator.getKey
4754
- }]
4758
+ }],
4759
+ dedupeIntervalMs: locator.dedupeIntervalMs
4755
4760
  });
4756
4761
  }
4757
4762
  }
@@ -8990,6 +8995,105 @@ function defaultItemToStringLabel(item) {
8990
8995
  return String(item);
8991
8996
  }
8992
8997
 
8998
+ // src/action-form/fields/FilePickerField.module.css
8999
+ var FilePickerField_default = {};
9000
+
9001
+ // src/action-form/fields/FilePickerField.tsx
9002
+ var FilePickerField = /* @__PURE__ */ React76.memo(function FilePickerFieldFn({
9003
+ id,
9004
+ value,
9005
+ onChange,
9006
+ isMulti,
9007
+ accept,
9008
+ // TODO: implement maxSize validation in a follow-up
9009
+ maxSize: _maxSize,
9010
+ text = "No file chosen",
9011
+ buttonText = "Browse"
9012
+ }) {
9013
+ const inputRef = React76.useRef(null);
9014
+ const openFileDialog = React76.useCallback(() => {
9015
+ inputRef.current?.click();
9016
+ }, []);
9017
+ const handleInputChange = React76.useCallback((event) => {
9018
+ const files = event.target.files;
9019
+ if (files == null || files.length === 0) {
9020
+ onChange?.(null);
9021
+ return;
9022
+ }
9023
+ if (isMulti) {
9024
+ onChange?.(Array.from(files));
9025
+ } else {
9026
+ onChange?.(files[0] ?? null);
9027
+ }
9028
+ }, [onChange, isMulti]);
9029
+ const handleClear = React76.useCallback((event) => {
9030
+ event.stopPropagation();
9031
+ event.preventDefault();
9032
+ onChange?.(null);
9033
+ if (inputRef.current != null) {
9034
+ inputRef.current.value = "";
9035
+ }
9036
+ }, [onChange]);
9037
+ const handleKeyDown = React76.useCallback((event) => {
9038
+ if (event.key === "Enter" || event.key === " ") {
9039
+ event.preventDefault();
9040
+ openFileDialog();
9041
+ }
9042
+ }, [openFileDialog]);
9043
+ const displayText = getDisplayText(value);
9044
+ const hasValue = displayText != null;
9045
+ const acceptString = normalizeAccept(accept);
9046
+ return (
9047
+ // The entire component is a single tab stop (tabIndex={0}).
9048
+ // Text and Browse are <span>s (not buttons) so they don't create
9049
+ // extra tab stops — clicks on them bubble up to the container's onClick.
9050
+ // The clear button is the only inner interactive element and gets its
9051
+ // own tab stop so keyboard users can clear the selection.
9052
+ /* @__PURE__ */ React76__default.default.createElement("div", {
9053
+ id,
9054
+ className: FilePickerField_default.osdkFilePickerTrigger,
9055
+ tabIndex: 0,
9056
+ role: "button",
9057
+ onClick: openFileDialog,
9058
+ onKeyDown: handleKeyDown
9059
+ }, /* @__PURE__ */ React76__default.default.createElement("input", {
9060
+ ref: inputRef,
9061
+ type: "file",
9062
+ className: FilePickerField_default.osdkFilePickerHiddenInput,
9063
+ multiple: isMulti,
9064
+ accept: acceptString,
9065
+ onChange: handleInputChange,
9066
+ "aria-hidden": "true",
9067
+ tabIndex: -1
9068
+ }), /* @__PURE__ */ React76__default.default.createElement("span", {
9069
+ className: classnames14__default.default(FilePickerField_default.osdkFilePickerText, !hasValue && FilePickerField_default.osdkFilePickerPlaceholder)
9070
+ }, displayText ?? text), hasValue && // stopPropagation + preventDefault prevent the click from
9071
+ // bubbling to the container's onClick which opens the file dialog.
9072
+ /* @__PURE__ */ React76__default.default.createElement(button.Button, {
9073
+ className: FilePickerField_default.osdkFilePickerClear,
9074
+ onClick: handleClear,
9075
+ "aria-label": "Clear selection"
9076
+ }, /* @__PURE__ */ React76__default.default.createElement(icons.Cross, null)), /* @__PURE__ */ React76__default.default.createElement("span", {
9077
+ className: FilePickerField_default.osdkFilePickerBrowse
9078
+ }, buttonText))
9079
+ );
9080
+ });
9081
+ function normalizeAccept(accept) {
9082
+ if (accept == null) {
9083
+ return void 0;
9084
+ }
9085
+ return Array.isArray(accept) ? accept.join(",") : accept;
9086
+ }
9087
+ function getDisplayText(value) {
9088
+ if (value == null) {
9089
+ return void 0;
9090
+ }
9091
+ if (Array.isArray(value)) {
9092
+ return value.map((f) => f.name).join(", ");
9093
+ }
9094
+ return value.name;
9095
+ }
9096
+
8993
9097
  // src/action-form/fields/NumberInputField.module.css
8994
9098
  var NumberInputField_default = {};
8995
9099
 
@@ -9266,12 +9370,29 @@ function renderFieldComponent(fieldDefinition, value, onChange) {
9266
9370
  placeholder: fieldDefinition.placeholder
9267
9371
  }, fieldDefinition.fieldComponentProps));
9268
9372
  case "FILE_PICKER":
9373
+ return /* @__PURE__ */ React76__default.default.createElement(FilePickerField, _extends13({
9374
+ id: fieldDefinition.fieldKey,
9375
+ value: coerceToFileValue(value),
9376
+ onChange
9377
+ }, fieldDefinition.fieldComponentProps));
9269
9378
  case "OBJECT_SET":
9270
9379
  return /* @__PURE__ */ React76__default.default.createElement("div", null, "Unsupported field type: ", fieldDefinition.fieldComponent);
9271
9380
  default:
9272
9381
  return assertUnreachableFieldComponent(fieldDefinition);
9273
9382
  }
9274
9383
  }
9384
+ function isFileArray(value) {
9385
+ return value.every((v) => v instanceof File);
9386
+ }
9387
+ function coerceToFileValue(value) {
9388
+ if (value instanceof File) {
9389
+ return value;
9390
+ }
9391
+ if (Array.isArray(value) && isFileArray(value)) {
9392
+ return value;
9393
+ }
9394
+ return null;
9395
+ }
9275
9396
  function assertUnreachableFieldComponent(value) {
9276
9397
  throw new Error(`Unhandled field component: ${String(value)}`);
9277
9398
  }