Skip to content

feat: add version history pattern demo - #939

Open
kaylachumley wants to merge 18 commits into
patternfly:mainfrom
kaylachumley:version-history-prototype
Open

kaylachumley wants to merge 18 commits into
patternfly:mainfrom
kaylachumley:version-history-prototype

Conversation

@kaylachumley

@kaylachumley kaylachumley commented Nov 2, 2026 •

Copy link
Copy Markdown

Jira RFE

Description

Adds a Version History pattern demo to support canvas mode.

Layout

Split-screen

Chatbot and canvas sit side by side by default. Open version history from the Version history split button in the canvas header (next to close)—use the main button or Show full history in the menu. The chatbot hides and the screen splits into a read-only code preview on the left and version history on the right. Close with the X to return to chatbot + canvas.

Features

  • Version list with names, timestamps, and AI/user attribution
  • Per-version actions: rename, restore, and duplicate
  • Split-button menu: show full history, restore latest version, name current version, save current version
  • Confirmation modal before restore
  • Read-only preview with copy and download when history is open
  • Save control on the editable code editor toolbar

Checklist

  • Split-screen demo (VersionHistorySplitScreen.tsx)
  • Split-screen v1 demo (VersionHistorySplitScreenV1.tsx)
  • Documentation (VersionHistory.md)
  • CSS styles (VersionHistory.css)

Preview

https://chatbot-pr-chatbot-939.surge.sh/patterns/version-history/demo/fullscreen-version-history/

https://chatbot-pr-chatbot-939.surge.sh

This adds a new Version History demo showcasing three layout options
for displaying version history in canvas mode:

- Option 1: Full overlay - version history replaces canvas panel
- Option 2: Split-screen - canvas (left) + version history (right) side-by-side
- Option 3: Floating panel - 75% overlay with floating background

Features include:
- Version list with timestamps and AI/user attribution
- Rename, restore, and duplicate version actions
- Confirmation modal for restore operations
- Read-only preview mode in split-screen layout

Co-authored-by: Cursor <cursoragent@cursor.com>
@patternfly-build

patternfly-build commented Nov 2, 2026 •

Copy link
Copy Markdown

kaylachumley and others added 17 commits November 2, 2026 10:34
Co-authored-by: Cursor <cursoragent@cursor.com>
- VersionHistoryOverlay: Full overlay that replaces the canvas panel
- VersionHistorySplitScreen: Side-by-side canvas preview and version list
- VersionHistoryFloating: 75% floating panel over the canvas

Each demo is now self-contained and can be viewed independently
without the need for a toggle switch.

Co-authored-by: Cursor <cursoragent@cursor.com>
The VersionHistory.css import from example TSX files was not bundled by
the docs framework, so the panel collapsed and hid the version list.
Import the CSS from patternfly-docs.css.js and make the overlay panel
fill the canvas drawer height.

Co-authored-by: Cursor <cursoragent@cursor.com>
Restores the X close control in the panel header so users can dismiss
version history and reopen it from the code editor toolbar.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the full overlay version history demo so the PR focuses on the
two preferred layout options.

Co-authored-by: Cursor <cursoragent@cursor.com>
Place the history icon button in the canvas panel header instead of
the code editor toolbar.

Co-authored-by: Cursor <cursoragent@cursor.com>
Restore the fullscreen chatbot + canvas default view, place the version
history trigger in the canvas header, and show the split-screen layout
only while version history is open. Update docs and PR description to
remove the full overlay option.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the default chatbot + canvas view identical to the local prototype.
Only relocate the version history trigger from the code editor toolbar
into the canvas header DrawerActions next to close.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep only the split-screen demo and related documentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve the previous icon-button trigger as SplitScreenV1. Replace the
header control with a MenuToggle split action labeled Version history,
including a dropdown of upcoming actions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Complete restore/name/save flows, restore editor toolbar actions, use
default split MenuToggle styling with md spacer, and fix DataList
clickable row selection/hover.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add missing MenuToggleAction/RhUiSaveIcon docs imports so the Surge
demo no longer throws, and fix eslint/prettier issues in both demos.

Co-authored-by: Cursor <cursoragent@cursor.com>
Scope the drawer actions gap to the canvas head so it applies in the
default canvas panel, not only the split preview layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@andrew-ronaldson

Copy link
Copy Markdown
Contributor

image

This may get resolved with engineer input but noticed the code editor and chatbot both have some responsive issues where it adds a horizontal scroll bar

@rebeccaalpert rebeccaalpert left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm writing these comments largely for myself so I know what to adjust, so I am not writing them as nicely as I would for other people!

There's a few things I'd want to change, but overall nice job!

  • We lose focus when we use dropdown items - focus goes to main container
  • When we save current version, second option is still highlighted even when new first option appears
  • Input is rather small on mobile:
Image
  • Need to rename CSS classes to match existing name format.


### Fullscreen version history

This demo shows a read-only code preview (canvas view) on the left and version history list on the right, utilizing a split-screen layout. Open the version history with the split menu toggle in the canvas panel header (next to close)—click the main button or **Show full history** in the dropdown. The chatbot panel is automatically hidden when the version history toggle is triggered. Close the version history with the X icon button to return to the chatbot and canvas.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This demo shows a read-only code preview (canvas view) on the left and version history list on the right, utilizing a split-screen layout. Open the version history with the split menu toggle in the canvas panel header (next to close)—click the main button or **Show full history** in the dropdown. The chatbot panel is automatically hidden when the version history toggle is triggered. Close the version history with the X icon button to return to the chatbot and canvas.
This demo uses a split-screen layout to show a read-only code preview (canvas view) and version history list.

Sometimes the order will reverse in Hebrew, etc.


## Class names

This demo reuses the [canvas](/patterns/canvas) `pf-chatbot__canvas*` classes from `@patternfly/chatbot` for the canvas and editor chrome. The classes below are defined in this demo's stylesheet (`VersionHistory.css`) and are used for the version history panel and split-screen layout. They are not exported from `@patternfly/chatbot`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not exported from @patternfly/chatbot.

We can export them - I think we export the Canvas classes.

@@ -0,0 +1,102 @@
/* Version History Panel Styles */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you tuck VersionHistory.css in a new folder at the path chatbot/packages/module/src/VersionHistory and then add it to this file the way Canvas is, we can export the classes like the other canvas ones. You should then be able to drop the change in patternfly-docs.css.js.

import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/react-styles/css/components/InlineEdit/inline-edit.css';
import '@patternfly/chatbot/dist/css/main.css';
import './VersionHistory.css';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be able to drop with other CSS changes.

import PFIconLogoReverse from '../UI/PF-IconLogo-Reverse.svg';
import userAvatar from '../Messages/user_avatar.svg';
import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/react-styles/css/components/InlineEdit/inline-edit.css';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here? 🤔 Research this.

</ModalFooter>
</Modal>

<input {...getInputProps()} hidden />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check to make sure this is in ok spot

border-block-start: none;
}

/* Option 2: Split-screen layout styles */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment

justify-content: space-between;
padding: var(--pf-t--global--spacer--md);
padding-top: var(--pf-t--global--spacer--lg);
padding-bottom: var(--pf-t--global--spacer--md);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to switch padding-top/bottom to padding-block-start, etc.

}

.version-history-split-panel {
width: 400px;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coded width - check to make sure this looks ok on breakpoints.


.version-history-split-panel {
width: 400px;
flex-shrink: 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this seems to fix iPhone SE issue

<MenuToggleAction
id="version-history-split-action"
key="version-history-action"
aria-label="Version history"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be adding an aria-label since there's visible text content to give this button an accessible name

Suggested change
aria-label="Version history"

Comment on lines +873 to +882
<Flex
spaceItems={{ default: 'spaceItemsSm' }}
alignItems={{ default: 'alignItemsCenter' }}
flexWrap={{ default: 'nowrap' }}
>
<FlexItem>
<RhUiHistoryIcon aria-hidden />
</FlexItem>
<FlexItem>Version history</FlexItem>
</Flex>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the Flex layout in this button renders invalid markup (div elements inside the button). We could replace this with CSS instead and just render the icon and text content on their own (or inside span elements), then just apply some custom classes to target inside a CSS file.

Comment on lines +867 to +871
onClick={(event) => {
event.stopPropagation();
setIsVersionHistoryMenuOpen(false);
openVersionHistory();
}}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When clicking this "Version history" action, focus gets lost when the new view appears. Pressing the Tab key focuses the first CodeEditory action, but before that focus isn't visible. We could shift focus to the heading on the new view (would require giving the heading a tabindex of -1)

Comment on lines +622 to +630
<Button type="submit" variant="plain" aria-label="Save edits" icon={<CheckIcon />} />
</div>
<div className="pf-v6-c-inline-edit__action">
<Button
type="button"
variant="plain"
aria-label="Cancel edits"
icon={<TimesIcon />}
onClick={handleCancelCanvasTitle}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar issue as above, focus gets lost when clicking the save or cancel edit buttons. Focus should go back to the MenuToggle that originally opened the list of actions that contained the edit trigger.

Comment on lines +836 to +846
<Label
isClickable
variant="outline"
icon={<RhUiAiInfoIcon aria-hidden />}
role="button"
tabIndex={0}
aria-expanded={isGeneratedAiPopoverOpen}
onKeyDown={handleGeneratedAiLabelKeyDown}
>
Generated with AI
</Label>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be an issue in other demos, which if it is we can open a followup for those, but I'm notcing that wwhen this Label gets truncated, a tooltip doesn't render to show the full text content on hover/focus.

Comment on lines +750 to +752
aria-labelledby={`version-${version.id}`}
id={`version-action-${version.id}`}
aria-label="Version actions"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aria attributes don't actually get passed in to anything, and the Dropdown being passed to this component will have any necessary accessible name, so they can be removed

Suggested change
aria-labelledby={`version-${version.id}`}
id={`version-action-${version.id}`}
aria-label="Version actions"
id={`version-action-${version.id}`}

isOpen={openMenuVersionId === version.id}
onOpenChange={(isOpen) => setOpenMenuVersionId(isOpen ? version.id : null)}
toggle={(toggleRef) => (
<MenuToggle

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a tooltip

Comment on lines +777 to +779
<DropdownItem key="restore" onClick={() => handleRestoreVersion(version.id)}>
Restore this version
</DropdownItem>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When triggering this action via keyboard, focus gets lost and looks like placed at the end of the page. We should move focus somewhere more appropriate.

Comment on lines +780 to +782
<DropdownItem key="duplicate" onClick={() => handleDuplicateVersion(version.id)}>
Duplicate
</DropdownItem>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Focus gets lost upon activating this action as well, and gets moved back to the very beginning of the page. WWe should place focus back on the kebab toggle that was originally opened.

Comment on lines +889 to +900
<DropdownItem key="show-full-history" onClick={openVersionHistory}>
Show full history
</DropdownItem>
<DropdownItem key="restore-latest-version" onClick={handleRestoreLatestVersion}>
Restore latest version
</DropdownItem>
<DropdownItem key="name-current-version" onClick={handleNameCurrentVersion}>
Name current version
</DropdownItem>
<DropdownItem key="save-current-version" onClick={handleSaveCurrentVersion}>
Save current version
</DropdownItem>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except for the "Name current version" action, the other actions all lose focus upon activating. We need to place focus somewwhere appropriate when the view changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants