Skip to content

FIREFLY-1954: React Split Pane version upgrade#1977

Open
kpuriIpac wants to merge 6 commits into
devfrom
FIREFLY-1954-react-split-pane
Open

FIREFLY-1954: React Split Pane version upgrade#1977
kpuriIpac wants to merge 6 commits into
devfrom
FIREFLY-1954-react-split-pane

Conversation

@kpuriIpac

@kpuriIpac kpuriIpac commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Ticket: FIREFLY-1954
IFE PR: https://github.com/IPAC-SW/irsa-ife/pull/472

  • This PR upgrades Firefly from react-split-pane v0.1.92 to v3.2.0
  • The core changes are in DockLayoutPanel. v0 allowed sizing props to be applied at the parent SplitPane level, but v3 moves that to the individual Pane components.
    • collapsible split panel logic is also slightly altered now to handle v3's pane sizing requirement.
  • Changed several consumers of SplitPane (using react-split-pane directly) to use our SplitPanel wrapper instead
  • AdvancedADQL and TabPanel include timing fixes for react-split-pane's v3 onwards ResizeObserver-based layout
    • In AdvancedADQL in particular, earlier the code assumed DOM was present when the useEffect for Prism.highlighAll ran), but with v3.2.0 of react-split-pane using ResizeObserver for layout measurements, I noticed the Pane content can become available after the useEffect where we try to initialize Prism
      • This led to crashes and/or the SQL examples not being highlighted
      • So the new retry logic aims to fix this race issue. Could possibly be polished further by extracting the logic into a small separate hook. Open to other feedback as well.
  • The dockerfile change to Node 20 from Node 18 was needed because react-split-pane@3.2.0 declares node >= 20 and my Jenkins builds were failing without this change. I will talk to @loitly about this before deciding if we need to keep this.

Testing:
Firefly, Euclid, Spherex, Timeseries

  • Confirm visually in TAP, Advanced ADQL (Edit ADQL), tri view and bi view results, collapsible panels (spherex spectrophotometry) and in Timeseries that the results look good.
    • Split Pane is used in several places, like the TAP screen as well. Test visually and compare against dev/ops if needed. Move around the panes to make sure there's no bugs there.
  • Dev links, to compare the test builds against: Firefly Dev, Euclid Dev, Spherex Dev, Timeseries Dev

@kpuriIpac kpuriIpac added this to the 2026.2 milestone Jul 6, 2026
@kpuriIpac kpuriIpac self-assigned this Jul 6, 2026

@robyww robyww left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks good. It works in my testing. There are some style things that I don't really understand that I assume is because of the component.

my big question is: why vertical to horizontal ?

<Stack id='chart-pinned-sideBySide' overflow='hidden' flexGrow={1}>
<Stack flexGrow={1} position='relative'>
<SplitPanel split='vertical' defaultSize={400} style={{display: 'inline-flex'}} pKey='chart-sideBySide'>
<SplitPanel direction='horizontal' defaultSize={400} style={{display: 'inline-flex'}} pKey='chart-sideBySide'>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This strikes me as unexpected. did the layout change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See below, layout remains the same. Just the meaning of vertical/horizontal is swapped.


return (
<SplitPane split='vertical' defaultSize={200} style={{display: 'inline-flex', ...style}}>
<SplitPanel direction='horizontal' defaultSize={200} style={{display: 'inline-flex', ...style}} pKey='filter-editor'>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

again, when did vertical become horizontal

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes so this is a big (but easy) change from v0.x to v3.x, they swapped vertical and horizontal to match CSS flex direction. Hence all of these changes.

}
setVal(adqlKey, `SELECT TOP 1000 * FROM ${maybeQuote(insertTname,true)}`);
window.setTimeout( () => prismLiveRef.current.syncStyles?.(), 10);
window.setTimeout( () => prismLiveRef.current?.syncStyles?.(), 10);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You should define a function at the top of the component syncStyles that is

const syncStyles= window.setTimeout( () => prismLiveRef.current?.syncStyles?.(), 10);

@loitly loitly left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I’ve tested it, and it worked fine. However, I have a suggestion that you should consider.

Comment on lines +98 to +104
<Pane
key={idx}
{...paneProps[idx]}
style={paneStyle}
>
{child}
</Pane>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would expect Pane to be the wrapper used in SplitContent and not injected here. This container should translate the out-dated 'maxSize/minSize' props into minSize defaultSize, than pass-along to the children, which should be Pane since we use SplitContent in all of our split panes.

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.

+1. This way you won't need to define and maintain paneProps=[{}, {}] dedicatedly here and pass-through props will allow consumers of SplitContent to leverage new/better API of Pane if they decide to.

@jaladh-singhal jaladh-singhal 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.

@kpuriIpac this is thorough! I tested Firefly and spherex primarily and they are working great (and better than before esp since there's no flicker on dragging the split pane resizer).

One minor issue in collapsible panel that appears in SP results: when you collapse it, it's still 2-4px in height as opposed to 0px height on dev. But it's not a dealbreaker since collapsible panel needs work in future anyways to make it handle both vertical and horizontal cases.

Comment thread package.json
"react-router-dom": "^6.14.0",
"react-slick": "~0.31",
"react-split-pane": "~0.1",
"react-split-pane": "^3.2.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.

We generally pin the minor version too since some packages introduce breaking change in minor version too (not sure about react-split-pane, looks stable enough) and hence use ~ instead of ^. We had a long discussion over this last time I had to update package.json 😅 and I added that to our dev documentation.

const textArea = adqlEl.current?.querySelector('textarea');
// adopt textArea
prismLiveRef.current = new Prism.Live(textArea);
let cancelled = false;

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.

Might be worth abstracting this out as a hook since above useEffect follows same pattern and it obscures the two-line business logic.

Comment on lines +98 to +104
<Pane
key={idx}
{...paneProps[idx]}
style={paneStyle}
>
{child}
</Pane>

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.

+1. This way you won't need to define and maintain paneProps=[{}, {}] dedicatedly here and pass-through props will allow consumers of SplitContent to leverage new/better API of Pane if they decide to.

function CollapsibleSplitContent({sx={}, panelTitle, children, ...props}) {
const {isOpen, onToggle} = useContext(SplitContext);

// TODO: dynamically calculate styles based on the position of toggle button and split direction (passed as props)

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.

This is an important TODO that I'd advise against removing since this component isn't mature enough to handle both vertical and horizontal splits. If you want to remove it, we should at least add this note to docstring of this component and mark it @experimental

onDragStarted: () => setIsSplitterDragging(true),
onDragFinished: (currentSize) => {
setIsSplitterDragging(false);
setIsCollapsibleOpen(currentSize > collapsedSize); // update the open state after dragging

@jaladh-singhal jaladh-singhal Jul 11, 2026

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.

again these code comments (and below) were helpful to understand the complex layout manipulation code.

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.

4 participants