From ac45a9497f4aa6ece0957468dfc7808959f3e2a5 Mon Sep 17 00:00:00 2001 From: Dan Rukas Date: Mon, 29 Jun 2026 12:33:16 -0400 Subject: [PATCH] docs(site): add ui-next component documentation and upgrade Docusaurus (#6102) --- .../docs/configuration/configurationFiles.md | 1 + platform/docs/docs/configuration/ui.md | 161 + platform/docs/docs/configuration/url.md | 2 +- .../migration-guide/3p10-to-3p11/index.md | 3 +- .../migration-guide/3p12-to-3p13/colors.md | 99 + .../migration-guide/3p12-to-3p13/index.md | 3 +- .../3p8-to-3p9/1-segmentation/index.md | 3 +- .../docs/migration-guide/3p8-to-3p9/index.md | 3 +- .../3p9-to-3p10/3-UI/1a-Colors.md | 2 +- .../3-UI/3-Migration-3p10-Input.md | 2 +- platform/docs/docs/migration-guide/index.md | 3 +- .../customization-service/Measurements.md | 3 +- .../customization-service/Segmentation.md | 3 +- .../customization-service/StudyBrowser.md | 3 +- .../ViewportScrollbar.md | 3 +- .../customization-service/WorkList.md | 3 +- .../customization-service/advanced.md | 3 +- .../appearance-theming.md | 379 ++ .../customization-service/customRoutes.md | 2 +- .../customizationService.md | 5 + .../customization-service/viewportOverlay.md | 2 +- platform/docs/docs/platform/themeing.md | 168 - platform/docs/docusaurus.config.js | 99 +- platform/docs/package.json | 27 +- platform/docs/src/css/custom.css | 324 +- .../docs/src/pages/colors-and-theming.tsx | 994 +++++ platform/docs/src/pages/colors-and-type.tsx | 434 -- platform/docs/src/pages/components-list.tsx | 142 - platform/docs/src/pages/components.tsx | 265 -- .../pages/components/AllinOneMenuShowcase.tsx | 119 - .../src/pages/components/ButtonShowcase.tsx | 54 - .../src/pages/components/CheckboxShowcase.tsx | 31 - .../pages/components/CinePlayerShowcase.tsx | 45 - .../src/pages/components/ComboboxShowcase.tsx | 105 - .../src/pages/components/DataRowShowcase.tsx | 20 - .../src/pages/components/DialogShowcase.tsx | 82 - .../pages/components/DropdownMenuShowcase.tsx | 81 - .../pages/components/HoverCardShowcase.tsx | 39 - .../src/pages/components/InputShowcase.tsx | 35 - .../src/pages/components/LabelShowcase.tsx | 27 - .../pages/components/NumericMetaShowcase.tsx | 463 --- .../pages/components/PanelSectionShowcase.tsx | 52 - .../src/pages/components/PopoverShowcase.tsx | 43 - .../pages/components/ScrollAreaShowcase.tsx | 33 - .../src/pages/components/SelectShowcase.tsx | 44 - .../docs/src/pages/components/ShowcaseRow.tsx | 49 - .../src/pages/components/SliderShowcase.tsx | 34 - .../src/pages/components/SwitchShowcase.tsx | 24 - .../src/pages/components/TabsShowcase.tsx | 41 - .../src/pages/components/ToastShowcase.tsx | 158 - .../components/ToolButtonListShowcase.tsx | 90 - .../pages/components/ToolButtonShowcase.tsx | 54 - .../src/pages/components/TooltipShowcase.tsx | 50 - .../pages/components/_layout/CodeBlock.tsx | 45 + .../components/_layout/ComponentLayout.tsx | 120 + .../pages/components/_layout/ExampleBlock.tsx | 16 + .../components/_layout/InteractivePicker.tsx | 60 + .../pages/components/_layout/PageHeader.tsx | 18 + .../pages/components/_layout/PropsTable.tsx | 46 + .../src/pages/components/_layout/Section.tsx | 29 + .../components/_layout/TableOfContents.tsx | 101 + .../components/_layout/sidebar-config.ts | 51 + .../src/pages/components/all-in-one-menu.tsx | 410 ++ platform/docs/src/pages/components/button.tsx | 147 + .../docs/src/pages/components/checkbox.tsx | 129 + .../docs/src/pages/components/cine-player.tsx | 163 + .../docs/src/pages/components/combobox.tsx | 102 + .../docs/src/pages/components/data-row.tsx | 289 ++ .../docs/src/pages/components/data-table.tsx | 352 ++ platform/docs/src/pages/components/dialog.tsx | 189 + .../src/pages/components/dropdown-menu.tsx | 195 + .../docs/src/pages/components/hover-card.tsx | 304 ++ platform/docs/src/pages/components/icons.tsx | 327 ++ platform/docs/src/pages/components/index.tsx | 156 + platform/docs/src/pages/components/input.tsx | 121 + platform/docs/src/pages/components/label.tsx | 95 + .../docs/src/pages/components/numeric.tsx | 294 ++ .../src/pages/components/panel-section.tsx | 255 ++ .../docs/src/pages/components/popover.tsx | 144 + .../docs/src/pages/components/scroll-area.tsx | 129 + platform/docs/src/pages/components/select.tsx | 152 + platform/docs/src/pages/components/slider.tsx | 121 + .../src/pages/components/smart-scrollbar.tsx | 474 +++ .../src/pages/components/switch-toggle.tsx | 129 + platform/docs/src/pages/components/table.tsx | 216 + platform/docs/src/pages/components/tabs.tsx | 117 + platform/docs/src/pages/components/toast.tsx | 184 + .../src/pages/components/tool-button-list.tsx | 214 + .../docs/src/pages/components/tool-button.tsx | 158 + .../docs/src/pages/components/tooltip.tsx | 148 + platform/docs/src/pages/patterns.tsx | 210 - .../src/pages/patterns/DataRowExample.tsx | 89 - platform/docs/src/pages/patterns/index.tsx | 33 - .../pages/patterns/patterns-measurements.tsx | 134 - .../pages/patterns/patterns-segmentation.tsx | 503 --- .../pages/patterns/patterns-split-panel.tsx | 43 - .../docs/src/pages/patterns/patterns-tmtv.tsx | 393 -- platform/docs/src/theme/Footer/index.tsx | 141 + platform/docs/static/img/mgh-logo-white.svg | 78 + .../docs/static/img/theming-color-roles.png | Bin 0 -> 32875 bytes .../img/theming-dialog-01-select-theme.png | Bin 0 -> 67377 bytes .../static/img/theming-dialog-02-default.png | Bin 0 -> 33078 bytes .../static/img/theming-dialog-03-custom.png | Bin 0 -> 59109 bytes platform/docs/static/img/theming-layers.png | Bin 0 -> 19813 bytes platform/docs/static/img/theming-themes.png | Bin 0 -> 503300 bytes platform/docs/tailwind.config.js | 43 +- .../3p8-to-3p9/1-segmentation/index.md | 3 +- .../migration-guide/3p8-to-3p9/index.md | 3 +- .../3p9-to-3p10/3-UI/1a-Colors.md | 2 +- .../3-UI/3-Migration-3p10-Input.md | 2 +- .../version-3.11/migration-guide/index.md | 3 +- pnpm-lock.yaml | 3545 +++++++---------- 112 files changed, 9665 insertions(+), 6674 deletions(-) create mode 100644 platform/docs/docs/configuration/ui.md create mode 100644 platform/docs/docs/migration-guide/3p12-to-3p13/colors.md create mode 100644 platform/docs/docs/platform/services/customization-service/appearance-theming.md delete mode 100644 platform/docs/docs/platform/themeing.md create mode 100644 platform/docs/src/pages/colors-and-theming.tsx delete mode 100644 platform/docs/src/pages/colors-and-type.tsx delete mode 100644 platform/docs/src/pages/components-list.tsx delete mode 100644 platform/docs/src/pages/components.tsx delete mode 100644 platform/docs/src/pages/components/AllinOneMenuShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ButtonShowcase.tsx delete mode 100644 platform/docs/src/pages/components/CheckboxShowcase.tsx delete mode 100644 platform/docs/src/pages/components/CinePlayerShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ComboboxShowcase.tsx delete mode 100644 platform/docs/src/pages/components/DataRowShowcase.tsx delete mode 100644 platform/docs/src/pages/components/DialogShowcase.tsx delete mode 100644 platform/docs/src/pages/components/DropdownMenuShowcase.tsx delete mode 100644 platform/docs/src/pages/components/HoverCardShowcase.tsx delete mode 100644 platform/docs/src/pages/components/InputShowcase.tsx delete mode 100644 platform/docs/src/pages/components/LabelShowcase.tsx delete mode 100644 platform/docs/src/pages/components/NumericMetaShowcase.tsx delete mode 100644 platform/docs/src/pages/components/PanelSectionShowcase.tsx delete mode 100644 platform/docs/src/pages/components/PopoverShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ScrollAreaShowcase.tsx delete mode 100644 platform/docs/src/pages/components/SelectShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ShowcaseRow.tsx delete mode 100644 platform/docs/src/pages/components/SliderShowcase.tsx delete mode 100644 platform/docs/src/pages/components/SwitchShowcase.tsx delete mode 100644 platform/docs/src/pages/components/TabsShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ToastShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ToolButtonListShowcase.tsx delete mode 100644 platform/docs/src/pages/components/ToolButtonShowcase.tsx delete mode 100644 platform/docs/src/pages/components/TooltipShowcase.tsx create mode 100644 platform/docs/src/pages/components/_layout/CodeBlock.tsx create mode 100644 platform/docs/src/pages/components/_layout/ComponentLayout.tsx create mode 100644 platform/docs/src/pages/components/_layout/ExampleBlock.tsx create mode 100644 platform/docs/src/pages/components/_layout/InteractivePicker.tsx create mode 100644 platform/docs/src/pages/components/_layout/PageHeader.tsx create mode 100644 platform/docs/src/pages/components/_layout/PropsTable.tsx create mode 100644 platform/docs/src/pages/components/_layout/Section.tsx create mode 100644 platform/docs/src/pages/components/_layout/TableOfContents.tsx create mode 100644 platform/docs/src/pages/components/_layout/sidebar-config.ts create mode 100644 platform/docs/src/pages/components/all-in-one-menu.tsx create mode 100644 platform/docs/src/pages/components/button.tsx create mode 100644 platform/docs/src/pages/components/checkbox.tsx create mode 100644 platform/docs/src/pages/components/cine-player.tsx create mode 100644 platform/docs/src/pages/components/combobox.tsx create mode 100644 platform/docs/src/pages/components/data-row.tsx create mode 100644 platform/docs/src/pages/components/data-table.tsx create mode 100644 platform/docs/src/pages/components/dialog.tsx create mode 100644 platform/docs/src/pages/components/dropdown-menu.tsx create mode 100644 platform/docs/src/pages/components/hover-card.tsx create mode 100644 platform/docs/src/pages/components/icons.tsx create mode 100644 platform/docs/src/pages/components/index.tsx create mode 100644 platform/docs/src/pages/components/input.tsx create mode 100644 platform/docs/src/pages/components/label.tsx create mode 100644 platform/docs/src/pages/components/numeric.tsx create mode 100644 platform/docs/src/pages/components/panel-section.tsx create mode 100644 platform/docs/src/pages/components/popover.tsx create mode 100644 platform/docs/src/pages/components/scroll-area.tsx create mode 100644 platform/docs/src/pages/components/select.tsx create mode 100644 platform/docs/src/pages/components/slider.tsx create mode 100644 platform/docs/src/pages/components/smart-scrollbar.tsx create mode 100644 platform/docs/src/pages/components/switch-toggle.tsx create mode 100644 platform/docs/src/pages/components/table.tsx create mode 100644 platform/docs/src/pages/components/tabs.tsx create mode 100644 platform/docs/src/pages/components/toast.tsx create mode 100644 platform/docs/src/pages/components/tool-button-list.tsx create mode 100644 platform/docs/src/pages/components/tool-button.tsx create mode 100644 platform/docs/src/pages/components/tooltip.tsx delete mode 100644 platform/docs/src/pages/patterns.tsx delete mode 100644 platform/docs/src/pages/patterns/DataRowExample.tsx delete mode 100644 platform/docs/src/pages/patterns/index.tsx delete mode 100644 platform/docs/src/pages/patterns/patterns-measurements.tsx delete mode 100644 platform/docs/src/pages/patterns/patterns-segmentation.tsx delete mode 100644 platform/docs/src/pages/patterns/patterns-split-panel.tsx delete mode 100644 platform/docs/src/pages/patterns/patterns-tmtv.tsx create mode 100644 platform/docs/src/theme/Footer/index.tsx create mode 100644 platform/docs/static/img/mgh-logo-white.svg create mode 100644 platform/docs/static/img/theming-color-roles.png create mode 100644 platform/docs/static/img/theming-dialog-01-select-theme.png create mode 100644 platform/docs/static/img/theming-dialog-02-default.png create mode 100644 platform/docs/static/img/theming-dialog-03-custom.png create mode 100644 platform/docs/static/img/theming-layers.png create mode 100644 platform/docs/static/img/theming-themes.png diff --git a/platform/docs/docs/configuration/configurationFiles.md b/platform/docs/docs/configuration/configurationFiles.md index 75fb177e5..fa022921e 100644 --- a/platform/docs/docs/configuration/configurationFiles.md +++ b/platform/docs/docs/configuration/configurationFiles.md @@ -118,6 +118,7 @@ window.config = ({ servicesManager } = {}) => { Here are a list of some options available: +- `customizationService`: An array of customization module references and inline overrides applied at the global scope. This is how deployers enable optional features like the [Appearance & Theming](./ui.md) system and configure UI components without modifying core code. See [Customization Service](../platform/services/customization-service/customizationService.md) for the full syntax reference. - `disableEditing`: If true, it disables editing in OHIF, hiding edit buttons in segmentation panel and locking already stored measurements. - `maxNumberOfWebWorkers`: The maximum number of web workers to use for diff --git a/platform/docs/docs/configuration/ui.md b/platform/docs/docs/configuration/ui.md new file mode 100644 index 000000000..fd8379fed --- /dev/null +++ b/platform/docs/docs/configuration/ui.md @@ -0,0 +1,161 @@ +--- +sidebar_position: 5 +sidebar_label: UI & Appearance +title: UI & Appearance +summary: Overview of OHIF's UI system — the component library, theming and appearance customization, iconography, and the services that drive modals, dialogs, notifications, and viewport layout. +--- + +# UI & Appearance + +OHIF's user interface is built on **ui-next**, a component library purpose-built +for medical imaging workflows. It provides a consistent set of React components, +a token-based theming system, a curated icon set, and a collection of UI services +that manage runtime behavior like modals, notifications, and viewport layout. + +This page gives a high-level map of how these pieces fit together and where to +find detailed documentation for each. + +## Component Library + +The [component library](/components) is the foundation of every panel, toolbar, dialog, and +control in the viewer. Components are organized into three tiers: + +- **Simple components** — atomic building blocks like Button, Checkbox, Input, + Label, Slider, and Switch. These are styled with the design system's tokens and + are the smallest interactive units. + +- **Compound components** — composed from simple components to handle more + complex interactions: Select, Dialog, DropdownMenu, Tabs, Table, Popover, + Tooltip, Toast, and others. These manage their own state (open/close, selection, + focus) via headless patterns. + +- **OHIF-specific components** — built for medical imaging workflows and not + found in general-purpose libraries: AllInOneMenu, CinePlayer, DataRow, + DataTable, Numeric, PanelSection, SmartScrollbar, ToolButton, and + ToolButtonList. These integrate directly with OHIF's services and extension + system. + +Every component renders live in the interactive +[Components](/components) section of this documentation site, where you +can see props, variants, and copy usage examples. + +## Appearance Dialog + +The Appearance dialog is an optional UI that lets end users switch presets, +apply custom CSS overrides, and share themes via URL. It is not enabled by +default, but deployers can +[opt in via configuration](../platform/services/customization-service/appearance-theming.md#enabling-the-theme-module). +See [Appearance & Theming](../platform/services/customization-service/appearance-theming.md) +for the full setup and developer guide. + +## Colors & Theming + +OHIF uses a **token-based color system** built on CSS custom properties with HSL +values. The base theme (dark mode) is defined in `:root` via Tailwind CSS, and +theme presets override specific tokens by applying a CSS class to `document.body`. + +The theming system covers: + +- **[Design tokens](/colors-and-theming#color-tokens-and-roles)** — a set of semantic color variables (`--background`, + `--primary`, `--card`, `--border`, etc.) that every component references. Tokens + are defined as HSL triplets and consumed via Tailwind's `hsl(var(...))` pattern. + +- **Theme presets** — six built-in themes (three tonal, three neutral) that shift + the entire interface's color palette. Presets are defined as JSON files and + applied via CSS classes. Also see: + [Creating Themes](/colors-and-theming#creating-themes) and + [Adding a Theme Preset](../platform/services/customization-service/appearance-theming.md#adding-a-theme-preset). + +- **Accessibility** — foreground tokens are paired with every surface token to + maintain contrast ratios across themes. When adding custom themes, + [test colors to match accessibility standards](/colors-and-theming#accessibility). + +Explore the live token swatches and theme picker in the interactive +[Colors & Theming](/colors-and-theming) page, and see +[Appearance & Theming](../platform/services/customization-service/appearance-theming.md) +for the full configuration and developer guide. + +## Iconography + +OHIF ships a curated set of icons designed specifically for medical imaging interfaces. +Icons are SVG-based, registered via `addIcon()`, and rendered through the `Icons` +component. They follow the same token system as the rest of the UI, so icon colors +respond to the active theme. + +Browse the full set with search and click-to-copy in the +[Iconography](/components/icons) page. + +## White Labeling + +OHIF supports replacing the header logo with custom branding via the +`whiteLabeling` configuration key. This lets you rebrand the viewer without +modifying source code. + +Add a `whiteLabeling` entry to your configuration file with a +`createLogoComponentFn` that returns a React element: + +```js +window.config = { + /** .. **/ + whiteLabeling: { + createLogoComponentFn: function(React) { + return React.createElement( + 'a', + { + target: '_self', + rel: 'noopener noreferrer', + className: 'text-purple-600 line-through', + href: '/', + }, + React.createElement('img', { + src: './customLogo.svg', + }) + ); + }, + }, + /** .. **/ +}; +``` + +![custom-logo](../assets/img/custom-logo.png) + +You can use Tailwind CSS utility classes in the `className` property to style +your custom logo component. + +## UI Services + +While the component library handles what gets rendered, **UI services** handle +the runtime behavior: opening modals, showing notifications, managing viewport +layout, and coordinating dialogs. These services use a pub/sub architecture and +are accessed through the `servicesManager`: + +| Service | What it manages | +|---------|----------------| +| [Modal Service](../platform/services/ui/ui-modal-service.md) | Full-screen and contained modals (including the Appearance dialog) | +| [Dialog Service](../platform/services/ui/ui-dialog-service.md) | Lightweight dialogs with form inputs and confirmations | +| [Notification Service](../platform/services/ui/ui-notification-service.md) | Toast notifications (success, warning, error, info) | +| [Viewport Grid Service](../platform/services/ui/viewport-grid-service.md) | Viewport layout, grid arrangement, and active viewport tracking | +| [Viewport Dialog Service](../platform/services/ui/ui-viewport-dialog-service.md) | Dialogs anchored to specific viewports | +| [Viewport Action Menu](../platform/services/ui/viewport-action-menu.md) | Context menus and action buttons on viewport corners | +| [Cine Service](../platform/services/ui/cine-service.md) | Cine playback controls and frame rate | + +UI services are documented in the [Services > UI](../platform/services/ui/index.md) +section. + +## Customization Service + +The [Customization Service](../platform/services/customization-service/customizationService.md) +is the mechanism that ties everything together. It allows deployers and +extension authors to override, extend, or replace UI components and behaviors +without modifying core code. Customizations can be scoped to a specific mode, set +globally via configuration, or provided as defaults by extensions. + +The Appearance dialog itself is delivered as a customization module. Deployers +enable it by adding a single reference to their config's `customizationService` +array. This pattern means that any part of the UI that supports customization +can be configured the same way. + +See the full customization guide at +[Customization Service](../platform/services/customization-service/customizationService.md), +including the syntax reference for `$set`, `$push`, `$merge`, `$filter`, and +other operations. diff --git a/platform/docs/docs/configuration/url.md b/platform/docs/docs/configuration/url.md index 2fa3a736d..69faf7a1b 100644 --- a/platform/docs/docs/configuration/url.md +++ b/platform/docs/docs/configuration/url.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 sidebar_label: URL title: URL Parameters summary: Reference for OHIF Viewer URL parameters that control WorkList filtering, study/series loading, and viewer behavior, including parameters for filtering by patient name, modality, data sources, specifying initial series/instances, and selecting hanging protocols. diff --git a/platform/docs/docs/migration-guide/3p10-to-3p11/index.md b/platform/docs/docs/migration-guide/3p10-to-3p11/index.md index 90c2dfc5b..5001f9f64 100644 --- a/platform/docs/docs/migration-guide/3p10-to-3p11/index.md +++ b/platform/docs/docs/migration-guide/3p10-to-3p11/index.md @@ -6,10 +6,9 @@ title: 3.10 to 3.11 Migration Guide --- import DocCardList from '@theme/DocCardList'; -import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; # 3.10 to 3.11 Migration Guide Here you can find the migration guides for upgrading from OHIF version 3.10 to version 3.11. - item.docId !== 'migration-guide/3p10-to-3p11/index')}/> + diff --git a/platform/docs/docs/migration-guide/3p12-to-3p13/colors.md b/platform/docs/docs/migration-guide/3p12-to-3p13/colors.md new file mode 100644 index 000000000..f0f7f31dd --- /dev/null +++ b/platform/docs/docs/migration-guide/3p12-to-3p13/colors.md @@ -0,0 +1,99 @@ +--- +sidebar_position: 7 +sidebar_label: Color System +title: Color System Migration +summary: 3.13 continues the migration from legacy color classes to the ui-next semantic color system. This guide maps legacy color names to their ui-next equivalents and shows common text, background, and border replacements. +--- + +# Color System Migration + +This guide covers migrating from legacy color classes to the new ui-next color system. + +## Current State (3.13+) + +The OHIF Viewer is now built entirely with ui-next components, which use the [new color system](/colors-and-theming). The legacy components in `platform/ui` remain on the old color system. For reference, the table below maps the legacy colors to their ui-next equivalents. + +## Color Mapping Reference + +| Legacy Color | Updated color (ui-next) | +| ----------------- | ----------------------- | +| `bkg-low` | `background` | +| `common-bright` | `foreground` (various) | +| `primary-light` | `highlight` | +| `inputfield-main` | `input` | +| `secondary-light` | `input` | +| `primary-dark` | `muted` | +| `bkg-med` | `muted` | +| `aqua-pale` | `muted-foreground` | +| `secondary-dark` | `popover` | +| `primary-active` | `primary` | +| `actions-primary` | `primary` | +| `secondary-main` | | +| `primary-main` | | +| `common-dark` | | +| `customblue` | | + +> **Note:** The legacy variables left blank in the table above (`secondary-main`, `primary-main`, `common-dark`, and `customblue`) have no direct ui-next equivalent. If your code uses any of these, replace them case by case, choosing the semantic token that best fits how the color is used in each component. + +## Generic Color Migrations + +Avoid using generic color values. Use semantic colors instead: + +| Generic Color | Semantic Replacement | +| ---------------------------- | ----------------------- | +| `white` | `foreground` | +| `blue-*` (e.g., `blue-500`) | `primary` or `highlight`| +| `gray-*` (e.g., `gray-800`) | `muted` or `popover` | +| `red-*` | `destructive` | + +> **Note:** `black` is still used in certain cases to replace default browser backgrounds and to match imaging backgrounds. + +## Common Migrations + +### Text Colors + +```diff +- text-white ++ text-foreground + +- text-primary-light ++ text-highlight + +- text-primary-active ++ text-primary + +- text-secondary-light ++ text-muted-foreground +``` + +### Background Colors + +```diff +- bg-primary-dark ++ bg-muted + +- bg-secondary-dark ++ bg-popover + +- bg-black ++ bg-background +``` + +### Border Colors + +```diff +- border-secondary-light ++ border-input + +- border-primary-light ++ border-highlight + +- border-primary-dark ++ border-muted +``` + +## Important Notes + +- Legacy colors without a mapping (empty cells) should be evaluated on a case-by-case basis +- The new color system uses CSS variables, enabling future theme support +- When migrating, test components visually to ensure proper contrast and accessibility diff --git a/platform/docs/docs/migration-guide/3p12-to-3p13/index.md b/platform/docs/docs/migration-guide/3p12-to-3p13/index.md index b4b327115..3bf5b80cd 100644 --- a/platform/docs/docs/migration-guide/3p12-to-3p13/index.md +++ b/platform/docs/docs/migration-guide/3p12-to-3p13/index.md @@ -6,7 +6,6 @@ title: 3.12 to 3.13 Migration Guide --- import DocCardList from '@theme/DocCardList'; -import { useCurrentSidebarCategory } from '@docusaurus/theme-common'; # 3.12 to 3.13 Migration Guide @@ -25,4 +24,4 @@ The largest changes in 3.13 are infrastructure-level: - **[SegmentationService](./segmentation-service.md)** — the `removeSegmentationRepresentations` method was renamed. - item.docId !== 'migration-guide/3p12-to-3p13/index')} /> + diff --git a/platform/docs/docs/migration-guide/3p8-to-3p9/1-segmentation/index.md b/platform/docs/docs/migration-guide/3p8-to-3p9/1-segmentation/index.md index b6fa29f88..62b3f9205 100644 --- a/platform/docs/docs/migration-guide/3p8-to-3p9/1-segmentation/index.md +++ b/platform/docs/docs/migration-guide/3p8-to-3p9/1-segmentation/index.md @@ -6,7 +6,6 @@ summary: Migration guide for segmentation architecture changes in OHIF 3.9, cove --- import DocCardList from '@theme/DocCardList'; -import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; :::info This migration involves significant architectural changes to the segmentation system. While we typically aim for incremental updates, the shift from a tool group-centric to a viewport-centric architecture was necessary to support OHIF 3.9's advanced visualization capabilities, and more flexible segmentation handling. @@ -15,4 +14,4 @@ Don't worry - we'll guide you through each change step by step! ::: - + diff --git a/platform/docs/docs/migration-guide/3p8-to-3p9/index.md b/platform/docs/docs/migration-guide/3p8-to-3p9/index.md index c6f3393c3..ca6936af2 100644 --- a/platform/docs/docs/migration-guide/3p8-to-3p9/index.md +++ b/platform/docs/docs/migration-guide/3p8-to-3p9/index.md @@ -7,8 +7,7 @@ summary: Migration guide for upgrading from OHIF 3.8 to 3.9, covering segmentati import DocCardList from '@theme/DocCardList'; -import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; ## Migration Guide Sections - + diff --git a/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/1a-Colors.md b/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/1a-Colors.md index 14b7313b4..e2b6664d6 100644 --- a/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/1a-Colors.md +++ b/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/1a-Colors.md @@ -12,7 +12,7 @@ summary: Migration guide for OHIF 3.10's new color system, explaining the transi * **Component Abstraction:** Some styling, especially for interactive elements like buttons, has been abstracted into components (e.g., `ViewportActionButton`, UI library buttons) which use predefined variants (`default`, `secondary`, `ghost`) instead of manual style combinations. :::note -You can look at the set of colors in the [Color System](/colors-and-type) +You can look at the set of colors in the [Color System](/colors-and-theming) ::: diff --git a/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/3-Migration-3p10-Input.md b/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/3-Migration-3p10-Input.md index a2b2e57aa..fab5b1bbc 100644 --- a/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/3-Migration-3p10-Input.md +++ b/platform/docs/docs/migration-guide/3p9-to-3p10/3-UI/3-Migration-3p10-Input.md @@ -13,7 +13,7 @@ This guide explains how to migrate from the existing `Input`, `InputNumber`, `In ## Why Migrate? - See the full list of components in the [Numeric Component Showcase](/components-list#numeric) + See the full list of components in the [Numeric Component](/components/numeric) The old components relied heavily on props, making them complex and difficult to maintain and apply custom styles. The new `Numeric` component provides a structured approach with a context-based API, reducing prop clutter and improving reusability. diff --git a/platform/docs/docs/migration-guide/index.md b/platform/docs/docs/migration-guide/index.md index a293b5cf4..e21738b62 100644 --- a/platform/docs/docs/migration-guide/index.md +++ b/platform/docs/docs/migration-guide/index.md @@ -6,10 +6,9 @@ summary: Introduction to OHIF migration guides covering the upgrade paths betwee import DocCardList from '@theme/DocCardList'; -import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; # Migration Guides Based on the version you are migrating from, you can find the migration guide for the latest version of the platform. - + diff --git a/platform/docs/docs/platform/services/customization-service/Measurements.md b/platform/docs/docs/platform/services/customization-service/Measurements.md index 2558e1f0a..ae9714303 100644 --- a/platform/docs/docs/platform/services/customization-service/Measurements.md +++ b/platform/docs/docs/platform/services/customization-service/Measurements.md @@ -1,7 +1,8 @@ --- +sidebar_label: Measurements title: Measurements Customization summary: Documentation for customizing OHIF's measurement tools and displays, including how to modify display formats, annotation behaviors, and tracking interfaces for medical imaging measurements. -sidebar_position: 4 +sidebar_position: 5 --- diff --git a/platform/docs/docs/platform/services/customization-service/Segmentation.md b/platform/docs/docs/platform/services/customization-service/Segmentation.md index c363ab365..c31677eb6 100644 --- a/platform/docs/docs/platform/services/customization-service/Segmentation.md +++ b/platform/docs/docs/platform/services/customization-service/Segmentation.md @@ -1,7 +1,8 @@ --- +sidebar_label: Segmentation title: Segmentation Customization summary: Documentation for customizing OHIF's segmentation tools and visualization options, including configuration for segment rendering, color schemes, and interaction behaviors for medical image segmentation workflows. -sidebar_position: 5 +sidebar_position: 6 --- diff --git a/platform/docs/docs/platform/services/customization-service/StudyBrowser.md b/platform/docs/docs/platform/services/customization-service/StudyBrowser.md index 30d65bbdc..e524166ea 100644 --- a/platform/docs/docs/platform/services/customization-service/StudyBrowser.md +++ b/platform/docs/docs/platform/services/customization-service/StudyBrowser.md @@ -1,7 +1,8 @@ --- +sidebar_label: Study Browser title: Study Browser Customization summary: Documentation for customizing OHIF's Study Browser component, including configuration options for thumbnails, sorting functions, and display formats to enhance study navigation and selection workflows. -sidebar_position: 6 +sidebar_position: 7 --- # Study Browser diff --git a/platform/docs/docs/platform/services/customization-service/ViewportScrollbar.md b/platform/docs/docs/platform/services/customization-service/ViewportScrollbar.md index 4d26df0a2..cbec4419b 100644 --- a/platform/docs/docs/platform/services/customization-service/ViewportScrollbar.md +++ b/platform/docs/docs/platform/services/customization-service/ViewportScrollbar.md @@ -1,7 +1,8 @@ --- +sidebar_label: Viewport Scrollbar title: Viewport Scrollbar Customization summary: Documentation for configuring OHIF viewport scrollbar behavior, including progress vs legacy mode, loaded/viewed tracking visuals, loading pattern behavior, timing controls, and viewportScrollbar.indicator (size + optional custom indicator). -sidebar_position: 7 +sidebar_position: 9 --- # Viewport Scrollbar diff --git a/platform/docs/docs/platform/services/customization-service/WorkList.md b/platform/docs/docs/platform/services/customization-service/WorkList.md index d4d955b9e..7f5adaa4e 100644 --- a/platform/docs/docs/platform/services/customization-service/WorkList.md +++ b/platform/docs/docs/platform/services/customization-service/WorkList.md @@ -1,7 +1,8 @@ --- +sidebar_label: Work List title: Work List Customization summary: Documentation for configuring the OHIF WorkList study-list route — selecting between the new (default) and legacy variants, the preview panel's series view (thumbnails, list, or both), and the columns shown in the study-list table. -sidebar_position: 9 +sidebar_position: 10 --- # Work List diff --git a/platform/docs/docs/platform/services/customization-service/advanced.md b/platform/docs/docs/platform/services/customization-service/advanced.md index 6f14b76c4..fa751b499 100644 --- a/platform/docs/docs/platform/services/customization-service/advanced.md +++ b/platform/docs/docs/platform/services/customization-service/advanced.md @@ -1,7 +1,8 @@ --- +sidebar_label: Advanced title: Advanced Customization summary: Documentation for advanced OHIF customization techniques, including inheritance patterns, transform functions, and dynamic assembly of customizations to create sophisticated configurations across the platform. -sidebar_position: 8 +sidebar_position: 11 --- diff --git a/platform/docs/docs/platform/services/customization-service/appearance-theming.md b/platform/docs/docs/platform/services/customization-service/appearance-theming.md new file mode 100644 index 000000000..512e3a44c --- /dev/null +++ b/platform/docs/docs/platform/services/customization-service/appearance-theming.md @@ -0,0 +1,379 @@ +--- +sidebar_position: 2 +sidebar_label: Appearance & Theming +title: Appearance & Theming +summary: Documentation for OHIF's appearance and theming system, including theme presets, custom themes, URL-based theme selection, and how to enable the Appearance dialog for your deployment. +--- + +# Appearance & Theming + +OHIF includes an optional theming system that lets users switch between visual +theme presets, apply custom CSS token overrides, and share themes via URL. The +system is **not enabled by default** — deployers opt in by adding a single +configuration line. + +## Enabling the Theme Module + +The theming system is delivered as a customization module in the default +extension. To enable it, add the module reference to the `customizationService` +array in your configuration file: + +```js +window.config = { + // ... + customizationService: [ + '@ohif/extension-default.customizationModule.theme', + ], + // ... +}; +``` + +This single line activates the entire theming system: + +- The **Appearance** menu item appears in the viewer header and study list + settings +- Users can switch between theme presets via a dropdown +- The active theme persists across sessions via `localStorage` +- Themes can be applied via URL parameter (`?theme=orchid`) +- Custom CSS token overrides can be pasted and applied + +### What Happens Without It + +When the theme module is not in the configuration: + +- No Appearance menu item is shown anywhere in the UI +- No theme provider is mounted in the component tree +- URL parameters like `?theme=orchid` have no effect +- No `localStorage` keys are read or written +- Zero runtime footprint — the theming code does not execute + +This opt-in design ensures that deployments that don't need theming pay no cost +for it. + +## Theme Presets + +OHIF ships with six built-in theme presets organized into two families: + +### Tonal Presets + +Tonal presets introduce a color hue throughout the interface — backgrounds, +borders, and surfaces all carry the theme's signature color. + +| Preset | Description | +|--------|-------------| +| **Orchid** | Purple/violet tones with warm highlights | +| **Arctic** | Cool blue tones with icy surfaces | +| **Verdant** | Green tones with natural, earthy surfaces | + +### Neutral Presets + +Neutral presets keep surfaces achromatic (grays and blacks) and use color only +for interactive elements and highlights. + +| Preset | Description | +|--------|-------------| +| **Midnight** | Deep blacks with subtle gray layering | +| **Slate** | Cool neutral grays with blue highlights | +| **Deep** | Rich dark surfaces with minimal contrast | + +### Selecting a Preset + +Open the Appearance dialog from the header menu (or study list settings) and +choose a preset from the Theme dropdown. The theme applies immediately and +persists across sessions. + +## URL-Based Theme Selection + +Themes can be applied via URL parameter, which is useful for sharing links with a +specific visual configuration: + +``` +https://your-ohif-instance.com/viewer?theme=orchid +``` + +Valid values are any preset name: `default`, `orchid`, `arctic`, `verdant`, +`midnight`, `slate`, `deep`. + +The URL parameter takes precedence over the stored theme. When a URL theme is +applied, it is also saved to `localStorage` so the user's session continues with +that theme after navigation. + +:::note +The `custom` theme value is deliberately not URL-addressable. Custom themes rely +on CSS stored in the user's `localStorage`, so a `?theme=custom` link would land +the app in a state with no CSS behind it. +::: + +## Custom Themes + +The Appearance dialog includes a custom theme feature that allows pasting CSS +variable overrides directly into the viewer. + +### How It Works + +1. Open the Appearance dialog +2. Click **Custom Theme** to expand the text area +3. Paste CSS variable declarations (one per line): + ```css + --background: 270 45% 6%; + --foreground: 280 15% 96%; + --card: 268 40% 10%; + --primary: 270 85% 65%; + --border: 268 30% 18%; + ``` +4. Click **Apply** + +The viewer parses the variables and injects them as CSS overrides into both +`:root` and `.dark` selectors. Invalid lines are silently skipped. If no valid +variables are found, the Apply button shows an error message. + +Click **Clear** to remove the custom theme and return to the default appearance. + +### Token Format + +Theme tokens use **HSL triplets without the `hsl()` wrapper** — just the three +space-separated values: + +``` +--token-name: hue saturation% lightness%; +``` + +For example: `--primary: 270 85% 65%` represents a purple hue at 85% saturation +and 65% lightness. + +### Available Tokens + +The theming system uses the same token set as the base OHIF design system. The +most commonly customized tokens are: + +| Token | Purpose | +|-------|---------| +| `--background` | Page/viewport background | +| `--foreground` | Default text color | +| `--card` | Surface color for cards and panels | +| `--popover` | Elevated surface color (dropdowns, tooltips) | +| `--primary` | Primary interactive color (buttons, links) | +| `--secondary` | Secondary surface color | +| `--muted` | Subdued background areas | +| `--muted-foreground` | Subdued text color | +| `--accent` | Accent surface color | +| `--border` | Border color | +| `--input` | Input field background | +| `--ring` | Focus ring color | +| `--highlight` | Highlight/selection color | +| `--destructive` | Error/destructive action color | + +Each token also has a corresponding `-foreground` variant for text on that +surface (e.g., `--card-foreground`, `--primary-foreground`). + +## Preset File Format + +Theme presets are defined as JSON files in +`platform/ui-next/src/themes/`. Each file follows this structure: + +```json +{ + "name": "orchid", + "label": "Tonal: Orchid", + "cssVars": { + "dark": { + "highlight": "292 75% 62%", + "background": "270 45% 6%", + "foreground": "280 15% 96%", + "card": "268 40% 10%", + "primary": "270 85% 65%", + "border": "268 30% 18%" + } + } +} +``` + +| Field | Description | +|-------|-------------| +| `name` | Internal identifier. Must be unique and URL-safe. Used as the CSS class name (`theme-{name}`) and `?theme=` value. | +| `label` | Display label shown in the Appearance dialog dropdown. | +| `cssVars.dark` | Object mapping token names to HSL triplet values. Only tokens that differ from the default theme need to be specified. | + +The corresponding CSS class is defined in `platform/ui-next/src/themes/themes.css` +and applies the token overrides when the class is added to `document.body`. + +## Adding a Theme Preset + +To add a new preset to the Appearance dialog dropdown, three files need to be +updated: + +### 1. Create the JSON file + +Add a new JSON file in `platform/ui-next/src/themes/`. Use an existing preset as +a template: + +```json +{ + "name": "ember", + "label": "Tonal: Ember", + "cssVars": { + "dark": { + "highlight": "15 85% 55%", + "background": "12 40% 5%", + "foreground": "20 15% 96%", + "card": "10 35% 9%", + "primary": "15 80% 50%", + "border": "12 25% 16%" + } + } +} +``` + +The `name` must be unique and URL-safe — it becomes the CSS class name +(`theme-ember`) and the `?theme=` URL value. Only include tokens that differ from +the default theme. + +### 2. Add the CSS class to `themes.css` + +Add a corresponding class in `platform/ui-next/src/themes/themes.css` with the +same token values: + +```css +/* ─── Tonal: Ember ──────────────────────────────────────────────────── */ + +.theme-ember { + --highlight: 15 85% 55%; + --background: 12 40% 5%; + --foreground: 20 15% 96%; + --card: 10 35% 9%; + --primary: 15 80% 50%; + --border: 12 25% 16%; + /* ... all tokens from the JSON */ +} +``` + +:::note +The JSON and CSS must define the same tokens with the same values. The JSON is +used for metadata (name, label) and validation. The CSS is what actually applies +the theme at runtime via the body class. +::: + +### 3. Register in the barrel export + +Import the JSON file and add it to the `themePresets` array in +`platform/ui-next/src/themes/index.ts`: + +```ts +import orchid from './orchid.json'; +import arctic from './arctic.json'; +import verdant from './verdant.json'; +import midnight from './midnight.json'; +import slate from './slate.json'; +import deep from './deep.json'; +import ember from './ember.json'; // add import + +export const themePresets: ThemePreset[] = [ + orchid, arctic, verdant, midnight, slate, deep, ember // add to array +]; +``` + +The order of the array determines the order in the dropdown menu. + +## Removing a Theme Preset + +To remove a preset, reverse the three steps above: + +1. **Remove from `index.ts`** — delete the import and remove it from the + `themePresets` array +2. **Remove from `themes.css`** — delete the `.theme-{name}` class block +3. **Delete the JSON file** — remove the file from `platform/ui-next/src/themes/` + +Users who had the removed theme active will fall back to the default theme on +their next visit — the provider validates stored theme names against the current +preset list and resets invalid values. + +## Architecture + +### How the Provider Registers + +The theming system uses OHIF's `serviceProvidersManager` to register its React +provider dynamically. During app initialization, the default extension's +`preRegistration` hook checks whether the theme module is present in the +configuration. If it is, `ActiveThemeProvider` is registered into the component +tree: + +``` +App initializes + → Default extension's preRegistration runs + → Checks config for 'customizationModule.theme' + → If present: registerProvider('activeTheme', ActiveThemeProvider) + → App.tsx builds the provider tree + → Picks up registered providers automatically +``` + +App.tsx has no knowledge of theming. The extension that provides the theme module +also decides whether to register its provider. + +### How the Menu Item Appears + +The Appearance menu item is gated by the customization service. Both the viewer +header (`ViewerHeader.tsx`) and the study list settings +(`StudyListSettingsPopover.tsx`) call: + +```tsx +const AppearanceModal = customizationService.getCustomization('ohif.appearanceModal'); +``` + +If the customization is not registered (because the theme module wasn't enabled), +the call returns `undefined` and no menu item is rendered. + +### State Management + +`ActiveThemeProvider` manages theme state via React context: + +- **Active theme**: stored in component state and `localStorage` (`ohif:theme`) +- **Custom CSS**: stored in component state and `localStorage` (`ohif:custom-theme-css`) +- **CSS classes**: applied to `document.body` (`theme-{name}`) +- **Custom styles**: injected via a `