diff --git a/common/changes/@itwin/manage-versions-react/enable-download_2026-10-29.json b/common/changes/@itwin/manage-versions-react/enable-download_2026-10-29.json
new file mode 100644
index 00000000..488e0265
--- /dev/null
+++ b/common/changes/@itwin/manage-versions-react/enable-download_2026-10-29.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@itwin/manage-versions-react",
+ "comment": "Add an enableDownload option to hide named-version downloads while preserving existing behavior by default.",
+ "type": "patch"
+ }
+ ],
+ "packageName": "@itwin/manage-versions-react"
+}
diff --git a/packages/modules/manage-versions/README.md b/packages/modules/manage-versions/README.md
index 799ecc71..2de7f0ab 100644
--- a/packages/modules/manage-versions/README.md
+++ b/packages/modules/manage-versions/README.md
@@ -27,6 +27,23 @@ const App = () => (
);
```
+## Download action
+
+`enableDownload` controls the Download action in a named version's More menu.
+It defaults to `true`, preserving existing behavior. Set it to `false` for
+experiences that should not offer named-version downloads:
+
+```jsx
+
+```
+
+This only removes the UI action; it does not change API permissions or the
+availability of other named-version actions.
+
## Development
When making changes to the src, run `rushx start` in the dev folder to enable source watching and rebuild, so the storybook dev-server will have access to updated code on successful code compilation.
diff --git a/packages/modules/manage-versions/src/common/configContext.tsx b/packages/modules/manage-versions/src/common/configContext.tsx
index 453e389a..38db2349 100644
--- a/packages/modules/manage-versions/src/common/configContext.tsx
+++ b/packages/modules/manage-versions/src/common/configContext.tsx
@@ -18,6 +18,7 @@ const ConfigContext = React.createContext<
stringsOverrides: ManageVersionsStringOverrides;
log?: LogFunc;
enableHideVersions: boolean;
+ enableDownload: boolean;
}
| undefined
>(undefined);
@@ -30,12 +31,15 @@ export type ConfigProviderProps = {
log?: LogFunc;
children: React.ReactNode;
enableHideVersions: boolean;
+ enableDownload?: boolean;
};
export const ConfigProvider = (props: ConfigProviderProps) => {
- const { children, ...rest } = props;
+ const { children, enableDownload = true, ...rest } = props;
return (
- {children}
+
+ {children}
+
);
};
diff --git a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx
index 28ae8d70..37589c14 100644
--- a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx
+++ b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx
@@ -113,6 +113,38 @@ describe("ManageVersions", () => {
});
});
+ it.each([undefined, true, false])(
+ "should respect enableDownload=%s without removing other actions",
+ async (enableDownload) => {
+ const { container } = renderComponent({
+ enableDownload,
+ enableHideVersions: true,
+ });
+
+ const row = await waitFor(() => {
+ const firstRow = container.querySelector(
+ ".iac-versions-table-body [role='row']"
+ );
+ expect(firstRow).not.toBeNull();
+ return firstRow as HTMLElement;
+ });
+
+ fireEvent.click(within(row).getByRole("button", { name: "More" }));
+
+ expect(
+ await screen.findByText(defaultStrings.updateNamedVersion)
+ ).toBeVisible();
+ expect(screen.getByText(defaultStrings.hide!)).toBeVisible();
+ if (enableDownload === false) {
+ expect(
+ screen.queryByText(defaultStrings.download)
+ ).not.toBeInTheDocument();
+ } else {
+ expect(screen.getByText(defaultStrings.download)).toBeVisible();
+ }
+ }
+ );
+
it("should show changesets table with data", async () => {
const { container } = renderComponent();
diff --git a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx
index d70c50a1..18965310 100644
--- a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx
+++ b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx
@@ -102,6 +102,10 @@ export type ManageVersionsProps = {
onTabChange?: (tab: ManageVersionsTabs) => void;
/** Enable hide versions feature */
enableHideVersions?: boolean;
+ /** Show the named-version download action.
+ * @default true
+ */
+ enableDownload?: boolean;
};
export enum ManageVersionsTabs {
@@ -205,6 +209,7 @@ const ManageVersionsComponent = (props: ManageVersionsProps) => {
currentTab = ManageVersionsTabs.Versions,
onTabChange,
enableHideVersions = false,
+ enableDownload = true,
} = props;
const toaster = useToaster();
@@ -628,6 +633,7 @@ const ManageVersionsComponent = (props: ManageVersionsProps) => {
stringsOverrides={stringsOverrides}
log={log}
enableHideVersions={enableHideVersions}
+ enableDownload={enableDownload}
>
diff --git a/packages/modules/manage-versions/src/components/ManageVersions/VersionsTab/VersionsTab.tsx b/packages/modules/manage-versions/src/components/ManageVersions/VersionsTab/VersionsTab.tsx
index 3f80b850..8df3597b 100644
--- a/packages/modules/manage-versions/src/components/ManageVersions/VersionsTab/VersionsTab.tsx
+++ b/packages/modules/manage-versions/src/components/ManageVersions/VersionsTab/VersionsTab.tsx
@@ -74,7 +74,8 @@ const VersionsTab = (props: VersionsTabProps) => {
nameFilter,
} = props;
const toaster = useToaster();
- const { stringsOverrides, imodelId, enableHideVersions } = useConfig();
+ const { stringsOverrides, imodelId, enableHideVersions, enableDownload } =
+ useConfig();
const tableInstance = React.useRef>();
const collapseAllRows = useCallback(() => {
@@ -205,7 +206,9 @@ const VersionsTab = (props: VersionsTabProps) => {
setIsUpdateVersionModalOpen(true);
},
},
- {
+ ];
+ if (enableDownload) {
+ mainToolbarActions.push({
title: stringsOverrides.download,
label: stringsOverrides.download,
icon: ,
@@ -214,8 +217,8 @@ const VersionsTab = (props: VersionsTabProps) => {
const { changesetIndex } = version;
await onDownloadClick(changesetIndex);
},
- },
- ];
+ });
+ }
if (enableHideVersions) {
mainToolbarActions.push({
title: isHidden ? stringsOverrides.unhide : stringsOverrides.hide,
@@ -229,6 +232,7 @@ const VersionsTab = (props: VersionsTabProps) => {
return mainToolbarActions;
},
[
+ enableDownload,
enableHideVersions,
onDownloadClick,
stringsOverrides.download,